You are given coins of different denominations and a total amount of moneyamount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return-1.
For the iterative solution, we think in bottom-up manner. Suppose we have already computed all the minimum counts up tosum, what would be the minimum count forsum+1?
public int coinChange(int[] coins, int amount) {
if(amount<1) return 0;
int[] dp = new int[amount+1]; // 记录 1 到 amount的最小组合
int sum = 0;
while(++sum<=amount) {
int min = -1; // 如果没有coin组合,维持 -1
for(int coin : coins) { //每个coin和sum比较
if(sum >= coin && dp[sum-coin]!=-1) { //只有sum大于等于coin的值 并且 sum – coin 是有coin组合的
int temp = dp[sum-coin]+1; // 当前临时组合值是
//如果 min还是初始-1. Temp 就是当前最小,否则比取temp 和 min中的最小值
min = min<0 ? temp : (temp < min ? temp : min);
}
}
dp[sum] = min; // 保留当前sum的最小coin组合
}
return dp[amount];
}
public int coinChange(int[] coins, int amount) {
if(amount<1) return 0;
return helper(coins, amount, new int[amount]);
}
// rem: remaining coins after the last step; count[rem]: minimum number of coins to sum up to rem
private int helper(int[] coins, int rem, int[] count) {
if(rem<0) return -1; // 如果剩余小于0,表示这种组合不正确
if(rem==0) return 0; // 真好为0,表示这种组合可以是一种候选
if(count[rem-1] != 0) return count[rem-1]; // 如果已经计算,直接返回。因为 count数组是 0 到 amount - 1
int min = Integer.MAX_VALUE;
for(int coin : coins) {
int res = helper(coins, rem-coin, count); // 求解 rem-coin的coin组合值,
if(res>=0 && res < min) //如果有(>0) 并且小于当前 min 更新 min = res + 1
min = 1+res;
}
count[rem-1] = (min==Integer.MAX_VALUE) ? -1 : min; // 记录当前rem 的最小coin组合值。
return count[rem-1];
}