「LeetCode每日一题」——322. 零钱兑换
322. 零钱兑换
链接:https://leetcode-cn.com/problems/coin-change/
难度:中等
题目
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。
思路
拿到这种题型,感觉就是动态规划。动态规划问题的一般形式就是求最值,求最值就是穷举所有的可能性。
动态规划穷举主要是存在重复子问题,而且还具备最优的子结构,这样才能有最值。最重要的还有状态转移方程,能写出来就完成了大部分了。
就这道题而言,肯定是重复子问题:拿硬币,也是具备最优的子结构:让每种类似的硬币数量最小,然后就是考虑状态转移方程了。
假设输入不同面额的硬币 coins = [coin1, coin2, coin3] , 总金额 amount
f(0) = 0
f(coin1) = 1
f(coin2) = 1
f(coin3) = 1
f(n) = min(f(n), f(n-coin1) + 1, f(n-coin2) + 1, f(n-coin3) + 1)
初始状态:
f(n) = [float("inf")] * (amount+1) 初始化为正无穷大
f(0) = 0
最后的转态转移方程为:


方案代码
解决方法:
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
cnt_list = [float("inf")] * (amount+1)
cnt_list[0] = 0
for coin in coins:
for i in range(coin, amount+1):
cnt_list[i] = min(cnt_list[i], cnt_list[i-coin] + 1)
if cnt_list[-1] == float("inf"):
return -1
else:
return cnt_list[-1]
原创文章,作者:flypython,如若转载,请注明出处:http://flypython.com/algorithm/leetcode/211.html
您必须登录才能发表评论。