01
Problem Statement
Given an integer array coins (different denominations) and an integer amount, return the fewest number of coins needed to make that amount. If that amount cannot be made by any combination of the coins, return -1. You may use each coin unlimited times.
- Each coin denomination can be used as many times as you want.
amountis non-negative; coins are positive integers.- If
amountis 0, return 0 (no coins needed).
02
Key Observations
- Let
dp[a]= minimum number of coins needed to make amounta. For eachafrom 1 toamount, we can try using one coin of denominationc(ifc <= a), leaving subproblema - c: sodp[a] = 1 + min(dp[a-c])over all coinscwithc <= a. - Base:
dp[0] = 0. Initialize otherdp[a]with a value larger than any possible answer (e.g.amount + 1); if after the loopdp[amount]is still that sentinel, return -1. - Order of iteration (a from 1 to amount) ensures that when we compute
dp[a], alldp[a-c]are already computed.
03
Approach
High-level: dp[a] = fewest coins to make amount a. For each a, try each coin c: if c <= a, dp[a] = min(dp[a], 1 + dp[a-c]). Base dp[0] = 0.
Steps:
dp[0] = 0; filldp[1..amount]withamount + 1(or Integer.MAX_VALUE - 1 to avoid overflow).- For
afrom 1 toamount: for eachcincoins, ifc <= athendp[a] = min(dp[a], 1 + dp[a-c]). - Return
dp[amount] > amount ? -1 : dp[amount].
04
Implementation
Java
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int a = 1; a <= amount; a++) {
for (int c : coins) {
if (c <= a) {
dp[a] = Math.min(dp[a], 1 + dp[a - c]);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}05
Test Cases
Example 1
Input
coins = [1,2,5], amount = 11
Expected
3Explanation
11 = 5+5+1.
06
Complexity Analysis
- Time: O(amount * len(coins)).
- Space: O(amount).
07
Follow-ups
- Return the actual combination of coins; count total number of ways to make amount.