【Leetcode】322. Coin Change
You are given coins of different denominations and a total amount of money amount. 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
.
Example 1:
coins = [1, 2, 5]
, amount = 11
return
3
(11 = 5 + 5 + 1)
Example 2:
coins = [2]
, amount = 3
return -1
.
Tips:給定一個coins[]數組,表示現有的硬幣類型;給定一個整數amount表示要組成的金錢總數。
根據coins[],求出組成amount所需的最少的硬幣數。
解法一:循環 :①初始化一個數組dp,並將數組中的值都賦值為Integer.MAX_VALUE;
② 兩層循環,第一層遍歷amount 第二層遍歷coins[].length,當總錢數減去一個硬幣的值小於0,證明無法組成該錢數,continue。或者上一步的dp值仍為初始值Integer.MAX_VALUE,也應continue;
都滿足條件時,dp選擇當前dp值與上一步dp值加一後的最小值,dp[i]=Math.min(dp[i],1+dp[i-coins[j]] );。
③如果無法組成amount這個錢數,就返回-1,否則返回dp[amount].
public int coinChange(int[] coins, int amount) { int[] dp= new int[amount+1]; for(int i=0;i<=amount;i++){ dp[i]=Integer.MAX_VALUE; } dp[0]=0;for(int i=1;i<=amount;i++){ for(int j=0;j<coins.length;j++){ if(i-coins[j]<0 ||dp[i-coins[j]]==Integer.MAX_VALUE) continue; dp[i]=Math.min(dp[i],1+dp[i-coins[j]] ); } } return dp[amount]==Integer.MAX_VALUE?-1:dp[amount]; }
解法二: 遞歸 :當前組成amount所需的硬幣數,與上一步有關.假設我們已經找到了能組成amount的最少硬幣數,那麽最後一步,我們可以選擇任意的一個硬幣,加入這個硬幣之前,組成的金錢數為r,這時,r = amount-coins[i](需要循環所有的coins)。依次向前推,直到r等於0
或者小於0.
public int coinChange(int[] coins, int amount) {
if (amount < 0)
return 0;
return coinChangeCore(coins, amount, new int[amount]);
}
private int coinChangeCore(int[] coins, int amount, int[] count) {
if (amount < 0)
return -1;
if (amount == 0)
return 0;
//剪枝
if (count[amount - 1] != 0)
return count[amount - 1];
int min = Integer.MAX_VALUE;
for (int i = 0; i < coins.length; i++) {
int ans = coinChangeCore(coins, amount - coins[i], count);
if (ans >= 0 && ans < min) {
min = 1 + ans;
}
}
count[amount - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
return count[amount - 1];
}
【Leetcode】322. Coin Change