问题描述
我现在在做Leetcode 322.Coin Change,问题如下:
你得到一个整数数组coins代表不同的硬币 面额和代表总金额的整数金额 钱。
返回您需要的最少数量的硬币 数量。如果这笔钱不能用任何组合来弥补 的硬币,返回 -1。
你可以假设你有无数种硬币。
示例 1:
输入:coins = [1,2,5],amount = 11 输出:3 解释:11 = 5 + 5 + 1
示例 2:
示例 3:
示例 4:
示例 5:
我试图通过自顶向下的 DP 记忆来解决它。我在辅助函数中设置了一个参数来记住计数。
class Solution:
def coinChange(self,coins: List[int],amount: int) -> int:
c = set(coins)
dp = [0] * (amount + 1)
def helper(a,count):
if a == 0:
return count
# if a in c:
# return 1 + count
if dp[a] != 0:
return dp[a]
res = math.inf
for coin in c:
if a - coin >= 0 and helper(a-coin,count+1) != -1:
res = min(res,helper(a-coin,count+1))
dp[a] = res if res < math.inf else -1
return dp[a]
return helper(amount,0)
但它不会通过这种情况:
[1,5] 100
结果应该是 20,但我得到了 92。
我整个下午都在试图弄清楚,但不确定我做错了什么。我希望你能给我一些我哪里出错的建议。
预先感谢您的帮助。
解决方法
!!!这是一个完整的解决方案!!!
好的,这是我对这个问题的解决方案(下面解释了想法):
def solve(lst,amount):
lst.sort(key=lambda x: x,reverse=True)
current_amount = 0
count = 0
for item in lst:
while True:
if current_amount + item == amount:
count += 1
current_amount += item
break
elif current_amount + item > amount:
break
elif current_amount < amount:
count += 1
current_amount += item
if current_amount == amount:
break
if current_amount != amount:
print(-1)
else:
print(count)
solve([1,2,5],100)
输出:20
说明:
!!!主要想法
首先,您必须从列表中的最大数字开始,因为它需要最少的添加量才能最接近或完全成为最终数量。
!!!
所以首先要做的是将列表从最大到最小的数字排序,如 .sort()
函数所示。
然后对于该列表中的每个数字(for 循环从列表中的第一项开始,因此是最大的数字)将它们放入 while True 循环中,以便它们不断添加到总数中,直到满足条件:
有3个条件:
当前数量(来自所有添加的)加上列表中的当前项目等于最终数量,在这种情况下,将计数加一并将当前项目添加到总数中,然后跳出循环>
-
如果当前数量+列表中的当前项目大于最终数量,则爆发(这确保不再添加此类数字)
-
最常用的是检查当前金额是否小于最后一个,但重要的是它们是
elif
语句,因为在这种情况下,如果一个语句事实证明是真的,它不会检查在这种情况下不需要的其余部分,因为否则即使您无法向当前金额添加更多以不超过最终金额,它也会是真的。 -
这个 if 语句在
while True
循环之外,并在while True
循环中“突破”一个数字时检查最终数量是否匹配,这是为了防止连续检查即使虽然结果已经实现了。
然后计算结果,如果当前数量与最终打印-1 不匹配,则打印计数