322. 零钱兑换
力扣题目链接(opens new window)
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
你可以认为每种硬币的数量是无限的。
示例 1:
- 输入:coins = [1, 2, 5], amount = 11
- 输出:3
- 解释:11 = 5 + 5 + 1
示例 2:
- 输入:coins = [2], amount = 3
- 输出:-1
示例 3:
- 输入:coins = [1], amount = 0
- 输出:0
示例 4:
- 输入:coins = [1], amount = 1
- 输出:1
示例 5:
- 输入:coins = [1], amount = 2
- 输出:2
提示:
- 1 <= coins.length <= 12
- 1 <= coins[i] <= 2^31 - 1
- 0 <= amount <= 10^4
思路:还是完全背包类问题,只是状态转移方程由max变成min
最初版本
class Solution(object):def coinChange(self, coins, amount):""":type coins: List[int]:type amount: int:rtype: int"""if amount == 0:return 0dp = [0]* (amount + 1)for j in range(1, amount + 1):if j % coins[0] == 0:dp[j] = j // coins[0]else:dp[j] = -1for i in range(1, len(coins)):for j in range(coins[i], amount + 1):if dp[j - coins[i]] != -1:if dp[j] == -1:dp[j] = dp[j - coins[i]] + 1else:dp[j] = min(dp[j], dp[j - coins[i]] + 1)return dp[amount]
发现判断-1逻辑太多了,改成最大值就不用那么麻烦了
最终版本
class Solution(object):def coinChange(self, coins, amount):""":type coins: List[int]:type amount: int:rtype: int"""dp = [float('inf')]* (amount + 1)dp[0] = 0for i in range(0, len(coins)):for j in range(coins[i], amount + 1):dp[j] = min(dp[j], dp[j - coins[i]] + 1)if dp[amount] == float('inf'):return -1return dp[amount]