給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
示例 1:
輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:
輸入: coins = [2], amount = 3
輸出: -1
說明:你可以認為每種硬幣的數量是無限的。
通過次數99,196提交次數246,948
在真實的面試中遇到過這道題?
兩種思路:dp+回溯剪枝
動態規劃:
1. 確認原問題和子問題。原問題:m金額,最少用多少硬幣;子問題:a+b=m,a金額和b金額最少用多少硬幣;
2. 確認狀態。dp[i]即代表金額為i,最少需要多少硬幣;
3. 確認邊界狀態的值。dp[0]=0,dp[coin in coins] = 1;
4. 狀態轉移方程。dp[i] = min(dp[i-(coin in coins)]+1)
注:dp的過程中要注意條件判斷,比如金額小於最小硬幣的時候不需要進行後面的步驟,或者dp[i-(coin in coins)]==-1的時候,表明無法找到這個金額的組合,所以不進行dp。
class
solution
dp[0]
=0;for
(int i =
1;i<=amount;i++)}
}return dp[amount];}
};
回溯+剪枝
題解區的大佬思路,更加直觀,更加快速,總的思路就是從大到小貪心的去找滿足條件的乙個解,根據這個解來大面積的剪枝。背後的邏輯是,這個題貪心出來的解,大部分能夠離最優解的距離不遠,由此可以排除大量的距離最優解很遠的解,由此來優化搜尋空間。步驟如下:
1. 將coins從大到小排序;
2. 貪心的從coins中取出最多個數的最大的coin來盡可能滿足當前金額,當無法找到解的時候,回溯,得到第乙個解,更新初始化為int_max的ret;
class
solution
void
coinchange
(vector<
int>
&coins,
int amount,
int count,
int&ret,
int index)
if(index==coins.
size()
)return
;for
(int k = amount/coins[index]
;k>=
0&&k+count};
leetcode322 零錢兌換
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11輸出 3解釋 11 5 5 1 示例 2 輸入 coins 2 amount 3...
leetcode 322 零錢兌換
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1示例 2 輸入 coins 2 amount ...
LeetCode 322 零錢兌換
322 零錢兌換 題目 給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1 示例 2 輸入 co...