
/**
minCoins[]:记录结果,minCoins[i],代表凑成金额i最少需要的硬币数;
将可用面值初始化minCoins[coin] = 1,其余为Integer.MAX_VALUE,代表无当前可用面额,需要后续用其他面额凑出() coin代表可用硬币面额
凑出为0的金额:minCoins[0] = 0(金额0,不需要任何硬币)
凑出为1的金额:minCoins[1] = minCoins[1] (1没办法凑,有就有没有就没有)
凑出为2的金额:Math.min(minCoins[2],minCoins[2 - coin:coins] + 1) 直接用面值2(有的话) 或先直接用一张小于等于2的面额,再加上凑出minCoins[2 - coin:coins]需要的硬币数
凑出为3的金额:Math.min(minCoins[3],minCoins[3 - coin:coins] + 1) 直接用面值3(有的话) 或先直接用一张小于等于3的面额,再加上凑出minCoins[3 - coin:coins]需要的硬币数
.........
凑出为i的金额:Math.min(minCoins[i],minCoins[i - coin:coins] + 1) 直接用面值i(有的话) 或先直接用一张小于等于i的面额,再加上凑出minCoins[i - coin:coins]需要的硬币数
minCoins[i - coin:coins] + 1; +1代表先用了一张面额为coin的硬币, minCoins[i - coin:coins]代表凑出i - coin需要的硬币(已经有了coin,还需要i-coin)
优化:
可用面值与1无需初始化,递推过程中会自动计算得出
初始化时将Integer.MAX_VALUE改为amount + 1,避免溢出(最多需要amount个1,amount + 1已经可以表示"不可能"且更安全)
*/
class Solution {
/**
minCoins[]:记录结果,minCoins[i],代表凑成金额i最少需要的硬币数;
将可用面值初始化minCoins[coin] = 1,其余为Integer.MAX_VALUE,代表无当前可用面额,需要后续用其他面额凑出() coin代表可用硬币面额
凑出为0的金额:minCoins[0] = 0(金额0,不需要任何硬币)
凑出为1的金额:minCoins[1] = minCoins[1] (1没办法凑,有就有没有就没有)
凑出为2的金额:Math.min(minCoins[2],minCoins[2 - coin:coins] + 1) 直接用面值2(有的话) 或先直接用一张小于等于2的面额,再加上凑出minCoins[2 - coin:coins]需要的硬币数
凑出为3的金额:Math.min(minCoins[3],minCoins[3 - coin:coins] + 1) 直接用面值3(有的话) 或先直接用一张小于等于3的面额,再加上凑出minCoins[3 - coin:coins]需要的硬币数
.........
凑出为i的金额:Math.min(minCoins[i],minCoins[i - coin:coins] + 1) 直接用面值i(有的话) 或先直接用一张小于等于i的面额,再加上凑出minCoins[i - coin:coins]需要的硬币数
minCoins[i - coin:coins] + 1; +1代表先用了一张面额为coin的硬币, minCoins[i - coin:coins]代表凑出i - coin需要的硬币(已经有了coin,还需要i-coin)
优化:
可用面值与1无需初始化,递推过程中会自动计算得出
初始化时将Integer.MAX_VALUE改为amount + 1,避免溢出(最多需要amount个1,amount + 1已经可以表示"不可能"且更安全)
*/
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
//初始化
Arrays.fill(dp,amount + 1);
dp[0] = 0;
//开始递推
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(coin <= i) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}
if(dp[amount] > amount) {
return -1;
}
return dp[amount];
}
}
612

被折叠的 条评论
为什么被折叠?



