InterviewPrepKit

Home / Coding / 2-D Dynamic Programming

Coin Change II

medium Original ↗
Solving tips
  • Recognize this as an unbounded (counting) knapsack: dp[i][a] = number of ways to make amount a using the first i coin types, summing 'skip this type' + 'use one more of this type'.
  • Process coin TYPES in the outer loop to count combinations (order-insensitive); putting the amount loop outside instead counts ordered permutations (that is Combination Sum IV) and overcounts.
  • Target O(coins x amount) time and O(amount) space with a 1-D array; iterate amount ASCENDING to encode unlimited reuse (descending would give the 0/1 'each coin once' semantics).
  • Pitfall: forgetting to seed dp[0]=1 (the empty combination) — without it every count collapses to 0.

Problem

You are given an integer amount and an array coins of distinct coin denominations. You have an unlimited supply of each coin. Return the number of distinct combinations of coins that sum exactly to amount.

Two combinations are the same if they use the same multiset of coins — order does not matter (1 + 2 and 2 + 1 count once). If no combination works, return 0.

Examples

  • amount = 5, coins = [1, 2, 5]4 — the combinations are 5, 2+2+1, 2+1+1+1, 1+1+1+1+1.
  • amount = 3, coins = [2]0 — you can only ever make even totals.
  • amount = 0, coins = [7]1 — the single empty combination makes 0.

Constraints

  • 1 <= coins.length <= 300
  • 1 <= coins[i] <= 5000, all denominations distinct
  • 0 <= amount <= 5000
  • The answer fits in a signed 32-bit integer.

An exponential enumeration of every combination blows up; you need a polynomial O(coins × amount) DP.

Think about it first

Hint 1 Because order does not matter, fix an order on the coin *types* and decide them one type at a time. That prevents counting `1+2` and `2+1` as different — you always "consider coin 1's usage, then coin 2's usage."
Hint 2 Make one axis "how many coin types you are allowed to use so far" and the other axis "the amount you still need." `dp[i][a]` = number of ways to form amount `a` using only the first `i` coin types.
Hint 3 For coin type `i` and amount `a`: either you don't use coin `i` at all (`dp[i-1][a]`), or you use at least one copy and stay on the same row because supply is unlimited (`dp[i][a - coins[i-1]]`). Base case: `dp[i][0] = 1`.
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.