【问题标题】:recursive coin change problem - count permutations递归硬币找零问题 - 计数排列
【发布时间】:2021-07-13 21:51:14
【问题描述】:

给定一个硬币列表和一个正整数 n>0,我需要找到总和为 n 的排列数。列表中的每个硬币都可以多次使用。例如 - 给定以下列表:lst = [1,3,4] 和 n=4,函数应返回 4:for : [1,1,1,1], [1,3], [3,1 ] 和 [4]。 我被要求给出一个递归解决方案。 我知道如何编写计算组合数的递归代码,但我不知道如何编写计算排列数的代码。

这是我的代码:

def coin_change(lst, n):
if n == 0:
    return 1
if len(lst) == 0:
    return 0
if n<0:
    return 0

return coin_change(lst, n-lst[0]) + coin_change(lst[1:], n)

谢谢

【问题讨论】:

  • 你能展示你找到组合的方法吗?这可能是排列问题的一个很好的起点。
  • 类似的问题已经不少了。您编写的一些代码已经有所帮助。然而,一种非常天真的方法是生成所有可能的排列,然后在返回递归时过滤掉那些与 n 不匹配的排列。
  • @Blckknght :我已将代码添加到帖子中

标签: python recursion coin-change


【解决方案1】:

你有一些问题。您一直在尝试减少列表,但由于允许重复,您不能这样做。您必须每次都尝试整个列表,直到总和超过计数。这可以满足您的要求:

track = []
def coin_change(lst, n, sofar=[]):
    if sum(sofar) == n:
        print("winner", sofar)
        track.append( sofar )
        return
    if sum(sofar) > n:
        return
    for i in lst:
        coin_change( lst, n, sofar+[i] )
    return track

print(coin_change([1,3,4], 4))

输出:

winner [1, 1, 1, 1]
winner [1, 3]
winner [3, 1]
winner [4]
[[1, 1, 1, 1], [1, 3], [3, 1], [4]]

另一种方法是使用yield 生成获胜者,并使用yield from 传递来自内部调用的获胜者。

【讨论】:

  • 谢谢!所以基本上当你计算排列而不是组合时,你不能避免循环?
  • 嗯,这真的是“替换组合”,对吧?这里真的没有办法避免循环,因为你必须在每一步都尝试每一个选项。
猜你喜欢
  • 2020-04-11
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 2022-11-19
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多