我试图自己解决LeetCode问题322。硬币兑换:
您将获得一个整数数组,表示不同面额的硬币,以及一个整数金额,表示总金额。
返回您需要的最少数量的硬币,以弥补该金额。如果这些硬币的任何组合都无法弥补这一数额,则返回-1。
你可以假设每种硬币的数量是无限的。
我似乎有一个错误,无法找出它。
我用DFS解决,基本上是说当目标达到0时,只需将所有的num
聚集在一个数组中,并动态地保持尽可能短的结果。这是问题的决策树:
这是我的解决方案:
from typing import List
class Solution:
def coinChange(self, nums: List[int], target: int) -> int:
def dfs(remainder):
if remainder<0:
return None
if remainder==0:
return []
shortest_combination=None
for num in nums:
print("target",remainder)
print("num",num)
result=dfs(remainder-num)
if result!=None:
combination=[*result,num]
if shortest_combination==None or len(combination)<len(shortest_combination):
shortest_combination=combination
return shortest_combination
return -1 if dfs(target)==None else len(dfs(target))
s=Solution()
s.coinChange([1,2,5],100)
我打印num
和余数
,我发现由于某种原因余数
从未达到0。基于DFS,如果我继续从100中减去1,我应该达到0,但不知何故,它没有达到任何num
。
你的算法是正确的,它确实达到了0,但是在这种情况下你不打印它(函数在打印前退出)。添加更多调试,您会看到它确实到达了基本情况,并回溯并正确标识了子解决方案。
真正的问题是,您使用DFS访问的树是指数级的,因此您可以多次解决相同的问题。如果您添加几行代码来实现记忆化,您将看到它完成了这项工作:
from typing import List
class Solution:
def coinChange(self, nums: List[int], target: int) -> int:
memo = {} # used for memoization
def dfs(remainder):
if remainder in memo: # already solved this problem?
return memo[remainder] # then return what we got last time
if remainder<0:
return None
if remainder==0:
return []
shortest_combination=None
for num in nums:
result = dfs(remainder-num)
if result!=None:
combination=[*result,num]
if shortest_combination==None or len(combination)<len(shortest_combination):
shortest_combination=combination
memo[remainder] = shortest_combination # memoize this solution
return shortest_combination
return -1 if dfs(target)==None else len(dfs(target))
s=Solution()
print(s.coinChange([1,2,5],100)) # 20
这个问题需要用动态规划来解决。给定任何value
,假设您已经计算了生成0的最小数量的硬币,...value-1
,要计算value
的最小数量的硬币,请查看value-coin1
,value-coin2,value-coin3,...,选择最小的,并添加一个。
实际上,编码这是你应该自己做的事情。
我在理解动态规划中的硬币兑换问题时遇到了一个小问题。简单地说,我必须用最少数量的硬币来兑换一笔钱。 我有n种面值为1=v1的硬币
在硬币系统C={c1,c2,…ck}中,应改变给定的数量x,以使每个硬币ci具有给定的重量wi。我们想计算可能变化的总重量。两种变化是不同的,如果他们包含在不同的顺序相同的硬币。 如何给出上述问题的动态规划递归?我知道最小硬币兑换问题的递归(即C(x)=min{C(x-C)1 for x
我编写的代码使用动态规划解决了基本的硬币兑换问题,并给出了进行兑换所需的最小硬币数量。但是我想把每个硬币的数量存储在最小的数字里。 我试图做的是初始化数组,就像散列一样,只要找到,它就会增加的数量,即。但这并不是我想要的方式,因为它每次发现对应于时都会添加硬币。因此,在最终答案中,数字不是硬币的最终计数。 代码如下:
但是我们不能这样做吗:(是给定的可用硬币的排序集,和是它的下标,是给定的最高价值硬币) 我写的东西有什么问题吗?虽然解决方案不是动态的,但不是更有效吗?
如果每枚硬币的数量是无限的,那么复杂性是O(n*m),其中是总变化,是硬币类型的数量。现在,当每种类型的硬币都受到限制时,我们必须考虑剩余的硬币。我设法使它与的复杂性使用另一个大小的,所以我可以跟踪每个类型的剩余硬币。有没有一种方法可以让复杂性变得更好?编辑:问题是计算进行精确给定更改所需的最少硬币数量以及我们使用每种硬币类型的次数
我一直在使用动态规划研究硬币兑换问题。我尝试制作一个数组fin[],其中包含索引所需的最小硬币数,然后打印它。我已经写了一个代码,我认为应该给出正确的输出,但我不明白为什么它没有给出准确的答案。例如:对于输入:4 3 1 2 3(4是要更改的金额,3是可用硬币的类型,1 2 3是硬币值列表)输出应该是:0 1 1 2(因为我们有1,2,3作为可用硬币,需要0个硬币更改0,1个硬币更改1,1个硬币更