Coin Change
Problem (restated)
Given coin denominations and amount, return the fewest coins to make that amount, or -1 if impossible. Unlimited coins of each denomination.
Intuition
dp[x] = min coins to make x. dp[0]=0; for each amount, try each coin: dp[x] = min(dp[x], dp[x-coin]+1).
Approaches
Bottom-up DP
Tested onlyIdea. Initialize dp with ∞ except dp[0]=0. Relax transitions for every coin.
Walkthrough. coins=[1,2,5], amount=11 → dp[11]=3 (5+5+1).
Trade-offs. Standard optimal. BFS by coin count also works (shortest path in coin graph).
export function coinChange(coins: number[], amount: number): number {
const INF = amount + 1;
const dp = new Array<number>(amount + 1).fill(INF);
dp[0] = 0;
for (let x = 1; x <= amount; x++) {
for (const c of coins) {
if (c <= x) dp[x] = Math.min(dp[x]!, dp[x - c]! + 1);
}
}
return dp[amount]! > amount ? -1 : dp[amount]!;
}
export function coinChange(coins: number[], amount: number): number {
const INF = amount + 1;
const dp = new Array<number>(amount + 1).fill(INF);
dp[0] = 0;
for (let x = 1; x <= amount; x++) {
for (const c of coins) {
if (c <= x) dp[x] = Math.min(dp[x]!, dp[x - c]! + 1);
}
}
return dp[amount]! > amount ? -1 : dp[amount]!;
}
Template connection
Classic unbounded knapsack / 1D DP.
Reflection
- Which pattern gave this away within 90 seconds?
- What changed from the standard template?
- What would break the current solution?