Python回溯排列算法中for循环逻辑及回溯失效问题求助
Python排列回溯算法疑问解答
问题代码
class Solution: def permute(self, nums: list[int]) -> list[list[int]]: res = [] def backtrack(path, visited): if len(path) == len(nums): res.append(path) return for i in range(len(nums)): print(i) print(path) print(visited) if not visited[i]: visited[i] = True backtrack(path + [nums[i]], visited) visited[i] = False backtrack([], [False] * len(nums)) return res print(Solution().permute(nums=[1, 2, 3]))
疑问解答
range(len(nums))如何实现对nums的迭代?range(len(nums))生成从0到len(nums)-1的整数序列,每个整数i对应nums的索引,通过nums[i]就能获取对应元素。这样循环会遍历nums的所有元素索引,确保每一层递归都有机会检查所有元素,为生成全排列提供遍历基础。if not visited[i]条件的作用?
这是元素选中状态的过滤标记,用来避免同一个元素被重复加入当前排列路径path。visited是和nums长度一致的布尔列表,visited[i] = True表示nums[i]已被选入当前路径,跳过该元素能保证排列中每个元素仅出现一次,符合全排列的定义。backtrack(path + [nums[i]], visited)如何助力排列生成?
path + [nums[i]]会创建一个新列表,把当前选中的元素追加到原有路径末尾,作为下一层递归的新路径。这种方式不会修改外层的path,保证回溯时各分支的路径独立性。- 传递
visited(列表为引用传递)并在递归前后修改其状态,实现元素选中状态的回溯,确保不同分支的排列生成互不干扰。
调试问题分析
你提到的“无法回溯到i=1、提前终止”是对调试输出的误解,这段代码的回溯逻辑本身是正确的,能够生成全部6种排列。
核心循环执行流程:
- 初始调用
backtrack([], [False, False, False]),进入循环i=0,标记visited[0]=True,递归调用backtrack([1], [True, False, False])。 - 在该递归层,循环
i=1,标记visited[1]=True,递归调用backtrack([1,2], [True, True, False])。 - 继续递归到
backtrack([1,2,3], [True, True, True]),满足终止条件,将[1,2,3]加入结果,返回上一层。 - 执行
visited[2]=False回溯,回到[1,2]层的循环,i=2循环结束;再执行visited[1]=False回溯,回到[1]层的循环,i=1循环结束;最后执行visited[0]=False回溯,回到初始层的循环,i=0循环结束。 - 初始层进入
i=1,标记visited[1]=True,开始生成以2开头的排列,以此类推,最终生成全部6种排列。
如果调试输出没看到i=1的后续执行,可能是只观察了前几个递归步骤,或者print输出被截断。实际运行代码会得到完整的全排列结果。
内容的提问来源于stack exchange,提问作者user21055738
相关产品推荐
相关产品推荐

