回溯算法调试疑问:current.remove执行两次等问题咨询
LeetCode {1,2,3}子集回溯算法调试疑问解答
疑问1:执行current.remove后,变量i为何从2变为1?
这是回溯的递归栈帧特性导致的:每个递归调用会生成独立的栈帧,栈帧里的i是局部变量。当你在i=2的递归分支(处理元素3)执行完current.remove后,当前栈帧被弹出,程序回到上一层递归的栈帧——也就是之前触发backtrack(i+1, ...)的那一层,这一层的i原本就是1,所以变量i会从2变回1。
疑问2:首次循环i到3退出后,current.remove为何连续执行两次?
当循环的start等于数组长度(比如start=3),循环直接退出,程序逐层回溯返回:
- 第一次
remove:从处理[1,2,3]的递归栈返回,执行current.remove去掉3; - 这次返回后,回到
i=2的循环分支,循环已执行完毕,继续回到上一层i=1的递归栈,执行第二次current.remove去掉2。
两次连续的remove是递归栈逐层返回时,每层必须执行的回溯清理操作。
疑问3:将{1,2,3}添加至结果后,第二次执行current.remove时,i为何从1变为2?
当[1,2,3]加入结果后:
- 第一次
remove去掉3,回到i=2的循环分支,循环结束后返回上一层递归(对应i=1的调用); - 执行第二次
remove去掉2后,程序回到最外层循环(start=0),此时原i=1的循环分支已执行完毕,循环变量i会自增到2,准备进入下一次循环(处理元素3的独立分支),所以你看到i从1变为2。
# 参考的回溯实现代码示例 def subsets(nums): res = [] def backtrack(start, current): res.append(current.copy()) for i in range(start, len(nums)): current.append(nums[i]) backtrack(i + 1, current) current.pop() # 对应问题中的current.remove操作 backtrack(0, []) return res
内容的提问来源于stack exchange,提问作者Timothy Smith
相关产品推荐
相关产品推荐

