解释了Python中此递归问题的说明
检查此示例代码是否进行回溯,有两种方法可以将变量i
附加到curr
之前,在回溯之前,此处(未注释)更新全局ANS 数组,而另一种方式没有(如下所示)。
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)
],[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
行为不同
check this sample code for backtracking, there are two ways I can append the variable i
to curr
before backtracking, the one here (not commented) updates the global ans
array, whereas the other way doesn't (shown below).:
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)
output here: result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
for the other way:
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)
output here: result = [[], [], [], [], [], []]
I wish to understand, what exactly changes here and why the global output array ans
behaves differently
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Curr+[I]
创建一个新对象,该对象将传递给下一个递归调用。因此,每当您将Curr>附加到
ANS
的情况稍后修改。当您使用
.append
和.pop
时,您一直通过一个对象,因此,当您将其附加到ANS
时,它是实际上,您一次又一次地附加的那个独特的对象。然后,您将继续更新该唯一对象,该对象将反映ans
的所有元素,因为它们是同一对象。处理Curr
在清除处理时给出您最终只有空的列表,即使在每个步骤Curr
实际上都具有您想要的值。您可以看到,首先添加此打印件以检查除此错误外,在这两种情况下,一切仍然与您期望的情况相同:
要修复第二版,您可以通过副本传递:
或当您附加到<<时复制代码> ans
curr+[i]
creates a new object which gets passed to the next recursive call. So whenever you then appendcurr
toans
with this version, you append a new object showing you a snapshot of whatcurr
is which won't later get modified.When you instead use
.append
and.pop
, you keep passing and having only one single object, so when you append it toans
it is really that unique object that you append everytime again and again. Then you will keep updating that unique object which will reflect on all element ofans
since they are the same object. Given at the end of processingcurr
gets cleared you end up having only empty lists everywhere, even if at every stepcurr
had actually the value you wanted.You can see that by adding this print first to check that apart from this bug, everything still works the same in both cases as you would expect:
To fix the second version, you can pass a copy instead:
or copy when you append to
ans