【问题标题】:explanation to this recursion problem in pythonpython中这个递归问题的解释
【发布时间】:2022-07-04 09:01:14
【问题描述】:

检查此示例代码以进行回溯,有两种方法可以在回溯之前将变量 i 附加到 curr,此处的一种(未注释)更新全局 ans 数组,而另一种方式则没有t(如下所示)。:

n = 4
k = 2
ans = []
def backtrack(first, curr):
    if len(curr)==k:
        ans.append(curr)
    for i in range(first, n+1):
        # curr.append(i)
        backtrack(i+1, curr+[i])
        # curr.pop()

curr = []
backtrack(1, curr)
print("result = ",ans)

在此处输出:result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

换一种方式:

n = 4
k = 2
ans = []
def backtrack(first, curr):
    if len(curr)==k:
        ans.append(curr)
    for i in range(first, n+1):
        curr.append(i)
        backtrack(i+1, curr)
        curr.pop()

curr = []
backtrack(1, curr)
print("result = ",ans)

在此处输出: result = [[], [], [], [], [], []]

我想了解,这里到底发生了什么变化,以及为什么全局输出数组 ans 表现不同

【问题讨论】:

  • 请创建一个完整的minimal reproducible example,具有2个完整的功能和你得到的结果...
  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。
  • 刚刚做了,感谢@julien 的提示

标签: python oop recursion backtracking object-oriented-analysis


【解决方案1】:

curr+[i] 创建一个新对象,该对象将传递给下一个递归调用。因此,每当您在此版本中将 curr 附加到 ans 时,您都会附加一个新对象,向您显示 curr 是什么的快照,以后不会被修改。

当您改为使用.append.pop 时,您会一直传递并且只有一个对象,因此当您将其附加到ans 时,它确实是您一次又一次地附加的唯一对象。然后,您将继续更新该唯一对象,该对象将反映ans 的所有元素,因为它们是同一个对象。在处理结束时给定curr 被清除,即使在每一步curr 实际上都有你想要的值,你最终也会在任何地方都只有空列表。

您可以看到,通过首先添加此打印来检查除了此错误之外,在这两种情况下,一切仍然与您预期的一样:

def backtrack(first, curr):
    print(first, id(curr), curr)
    # ... and the rest

要修复第二个版本,您可以传递一个副本:

curr.append(i)
backtrack(i+1, curr.copy())
curr.pop()

或在附加到ans时复制

ans.append(curr.copy())

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 2016-10-04
    • 2020-03-26
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2022-12-04
    相关资源
    最近更新 更多