題目描述
分析
這道題分析起來並不難。遞推公式也能分析出來,但是我當時寫的時候疑惑的一個問題就是:如何判斷硬幣組合的總額剛好等於需要的金額,因為這裡的dp陣列很明顯是組成總金額所需的最少硬幣個數。
我試著加了一個陣列儲存當前情況下的金額。但是想一下就知道這樣太笨了。實現起來也特別困難。
首先看一下程式碼隨想錄的程式碼:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for (int i = 0; i < coins.size(); i++) { // 遍歷物品
for (int j = coins[i]; j <= amount; j++) { // 遍歷揹包
if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值則跳過
dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
}
}
}
if (dp[amount] == INT_MAX) return -1;
return dp[amount];
}
};
它透過把dp陣列的初始值設定為INT_MAX,並在遍歷中設定條件if (dp[j - coins[i]] != INT_MAX)。
dp[0]設定為0是因為從0開始組合,也就是j == coins[i]的話,肯定能形成一種組合,而如果dp[j - coins[i]]為INT_MAX的話,就說明這個位置沒有被修改過,也就是說沒有一種組合的總金額剛好等於j,透過這種機制就能判斷出組合總額湊不齊總金額的情況。
在最後返回的時候也能看出來,如果do[amount]為INT_MAX的話,就返回-1,代表沒有組合的總額能等於amount