給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
【舉例】
輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
我們仍採取上次說的回溯轉動態規劃,來慢慢熟悉動態規劃解題思路。
public
intmincoins
(int
coins,
int amount)
return
proress
(coins,
0, amount);}
/** *
* @param coins coin陣列
* @param i 當前考慮的第i個面值coin
* @param rest 目前剩下需要換的錢
* @return
*/public
intproress
(int
coins,
int i,
int rest)
// 最少張數,初始為-1
int res =-1
;// 依次嘗試使用當前面值(coins[i])0張、1張,但不能超過rest
for(
int k =
0; k * coins[i]
<= rest; k++)}
return res;
}
找可變引數,如果看了回溯的**,馬上能確定分別是:硬幣面值coins[i]
、剩下的錢rest
。
構建表,二維陣列的行代表硬幣面值,列代表兌換面值,如下圖所示。注意,為了構建base case,我們必須要建立0硬幣面值,以及0兌換錢數,因為我把0面值放在了陣列最後,所以我們運算方向是自下向上的
隨後我們對base case進行初始賦值,當0面值時。只有當兌換錢總數為0,數量才是0,其他都是-1(不可達)
最為關鍵的一步,如何填寫非base case,我們要梳理清楚邏輯關係,首先賦值-1,然後我們考慮此時的coin[i]
能否構成,不能構成(coin[i] > rest)我們肯定不可達,如果coins[i] < rest ,這是就要看 rest - coins[i] 是否可達,如果不可達,那rest也不可達,如果可達,我們就要和之前沒有coins[i]參與的面值組成的rest比一比,誰更小。
以上這段文字需要細細品味,如果你覺得想起來有點吃力,請看下面兩張圖:
這兩張圖中,我希望你搞清楚紅色數字的來由,
public
intmincoins
(int
coins,
int amount)
int n = coins.length;
int[
] dp =
newint
[n +1]
[amount +1]
;// base case初始化
for(
int col =
1; col <= amount; col++
)for
(int i = n -
1; i >=
0; i--)}
}return dp[0]
[amount]
;}
Leetcode 322 面試題08 11 湊硬幣
322.給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。面試題08.11.給定數量不限的硬幣,幣值為25分 10分 5分和1分,編寫 計算n分有幾種表示法。結果可能會很大,你需要將結果模...
leetcode 322 動態規劃
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1輸入 coins 2 amount 3 輸出 1說明 你...
leetcode322 零錢兌換
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11輸出 3解釋 11 5 5 1 示例 2 輸入 coins 2 amount 3...