題目如下:
定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
例子:
輸入:coins =[1, 2, 5]
, amount =11
輸出:3
解釋:11 = 5 + 5 + 1
輸入:coins =[2]
, amount =3
輸出:-1首先可以很自然的想到用遞迴去解決這個問題,用遞迴去遍歷各種兌換的可能性,在其中記錄下需要硬幣最少的次數,如 11可以被 11個一元硬幣兌換,也可以由兩個五元 乙個一元3枚硬幣兌換。
遞迴式的編寫最重要的是結束條件,可以想到,在一次次迴圈中,當amount小於0時,代表著本次迴圈不能正確兌完硬幣,需要主動遞迴結束,開始下次迴圈。當amount等於0時,代表本次可以正確兌換,
自動跳出迴圈。
public但是遞迴會讓導致計算重複的節點,如 【1,2,3】 amount=11,會導致下圖情況class
coinsway
int res=integer.max_value;
public
int coinchange(int coins, int
amount)
helper(coins,amount,0);
if(res==integer.max_value)
return
res;
}public
void helper(int coins,int amount,int
count)
if(amount==0)
for(int i=0;i)}}
我們對其進行優化,進行記憶化遞迴,記憶化遞迴就是將已運算的結果進行儲存,如上圖我們對剩9元進行儲存,在下次遍歷到剩9元硬幣時就可以直接返回結果,不必再次遍歷
public下面使用自底向上也就是動態規劃,動態規劃就是將前面計算的結果拿來給後面用,因此如何定義就是乙個問題,在這個問題種,我們定義陣列res【amount+1】,代表陣列下標對應的硬幣元數所需的最小個數int coinchange2(int coins,int
amount)
public
int helper2(int coins,int amount,int
res)
if(amount==0) return 0;
if(res[amount-1]!=0)
int min=integer.max_value;
for(int i=0;i)
}res[amount-1]=min==integer.max_value?-1:min;
return res[amount-1];
}
public好了,硬幣兌換的問題就解決啦!int coinchange3(int coins,int
amount)
}res[i]=min;
}return res[amount]==integer.max_value?-1:res[amount];
}
動態規劃 零錢兌換
問題描述 給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。你可以認為每種硬幣的數量是無限的。比如coins 1,2,5 amount 11,11 5 5 1,最終結果為3 演算法思路 本...
零錢兌換(動態規劃)
leetcode 322 零錢兌換 給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1 示例 2...
零錢兌換 動態規劃
給定不同面額的硬幣coins和乙個總金額amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。你可以認為每種硬幣的數量是無限的。示例 1 輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1 示例 2 輸入 ...