動態規劃解決零錢兌換問題

2022-08-20 21:15:14 字數 1789 閱讀 5166

題目如下:

定不同面額的硬幣 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

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)}}

但是遞迴會讓導致計算重複的節點,如 【1,2,3】 amount=11,會導致下圖情況

我們對其進行優化,進行記憶化遞迴,記憶化遞迴就是將已運算的結果進行儲存,如上圖我們對剩9元進行儲存,在下次遍歷到剩9元硬幣時就可以直接返回結果,不必再次遍歷

public

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];

}

下面使用自底向上也就是動態規劃,動態規劃就是將前面計算的結果拿來給後面用,因此如何定義就是乙個問題,在這個問題種,我們定義陣列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 輸入 ...