题目描述
假设给你不同面额的硬币和一个金额amount。编写一个函数来计算构成该金额amount
所需的最少数量的硬币。如果这笔钱不能由任何硬币组合成,则返回-1。
思路
动态规划:
- 假设amount为10,硬币面额为[1,2,5,10],用dp[i]来表示金额i所需要的最少硬币数,那么显然dp[0]=0,因为金额0不需要任何硬币。
- 此时如果我们取了个硬币5,显然dp[10]=dp[10-5]+1=dp[5]+1,那么此时dp[5]+1是最小值吗?不一定,因为如果取一枚金额为10的硬币就足够了,此时dp[10]=dp[10-10]+1=0+1=1.所以我们需要在取me某一枚硬币之后,需要更新当前dp[i]的值。
dp[i]=min(dp[i],dp[i-coin]+1)
- 另外我们需要初始化dp,假设每一个硬币的面额都大于amount,此时我们是找不出硬币组合的,那么dp[amount]=-1,显然我们不能初始化所有值为-1(负数小于任何正数),我们应该初始化一个“最大值”,比如inf或者amount+1,当遍历所有金额之后,最后dp[amount]仍然为'最大值',说明这笔钱不能由任何硬币组合成,那么我们返回-1。取amount+1是因为:假设所有硬币金额都为1,那么dp[amount]的最大值都为amount,都会小于amount+1
代码实现
class Solution: def coinChange(self, coins: List[int], amount: int) -> int: dp=[amount+1]*(amount+1) dp[0]=0 for i in range(1,amount+1): for c in coins: if i>=c: dp[i]=min(dp[i],dp[i-c]+1) if dp[amount]==amount+1: return -1 return dp[amount]
参考资料
- Python DP Solution -- Coin Change - LeetCode Discuss
- Leetcode No.322( Coin Change) 心得(Medium) – ChingYuanYang – Medium
- DP: 322. Coin Change Java – Bear熊 – Medium
- [LeetCode] Coin Change 硬币找零 - Grandyang - 博客园
- LeetCode 322. Coin Change 动态规划 - 简书
- leetcode 322. Coin Change-硬币交换|动态规划 - lovechara - CSDN博客
- LeetCode 322. Coin Change Python 动态规划/BFS解法 - 小鹅鹅的博客 - CSDN博客