322. 零錢兌換
知識點:動態規劃
題目描述
給你一個整數陣列 coins ,表示不同面額的硬幣;以及一個整數 amount ,表示總金額。
計算並返回可以湊成總金額所需的 最少的硬幣個數 。如果沒有任何一種硬幣組合能組成總金額,返回 -1 。
你可以認為每種硬幣的數量是無限的。
示例
輸入:coins = [1, 2, 5], amount = 11
輸出:3
解釋:11 = 5 + 5 + 1:
輸入:coins = [2], amount = 3
輸出:-1
輸入:coins = [1], amount = 0
輸出:0
輸入:coins = [1], amount = 1
輸出:1
輸入:coins = [1], amount = 2
輸出:2
解法一:動態規劃
- 1.確定dp陣列和其下標的含義;dp[i]表示金額為i時所需要的最少硬幣個數;
- 2.確定遞推公式,即狀態轉移方程;有兩種可能,1.有coin[i],也就是說如果某個小於當前金額i的j加上一個硬幣值coin就等於現在要求的金額,即j+coin=i,那dp[i] = dp[j] + 1;也就是金額為j時的最小值+這次的coin。2.不存在這一個coin面值,那要兌換的硬幣數量就是dp[i];
- 3.dp初始化;base case; 最上面的元素,也就是dp[0]=0;同時對其他dp填充為amount+1,因為這是不可能的情況,其實就相當於初始化為正無窮,便於後面取最小值;
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
Arrays.fill(dp, amount+1); //dp初始化為正無窮;
dp[0] = 0;
for(int i = 1; i < amount+1; i++){
for(int coin:coins){
if(i - coin < 0){
continue; //湊不出這個i,無解;
}
dp[i] = Math.min(dp[i], dp[i-coin]+1); //狀態轉移;
}
}
return (dp[amount] == amount+1) ? -1 : dp[amount];
}
}