You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何计算列表全排列的回溯算法无法返回所有排列且结果重复?

全排列回溯算法错误原因分析

你实现的全排列代码存在两个关键问题,导致输入[1,2,3]时输出全是[1,2,3]:

1. 仅添加列表引用而非副本

当执行res.append(nums)时,你向结果列表中添加的是nums列表的内存引用,而非当前状态下的列表副本。后续的回溯交换操作会直接修改这个列表的内容,最终res里的所有元素都会指向同一个列表——回溯完成后恢复初始状态的[1,2,3]。

解决方法:添加列表的副本到结果中,替换为:

res.append(nums.copy())  # 或者 nums[:]

2. 循环范围与终止条件不匹配

原代码中length = len(nums) - 1,循环用range(l, length),这会导致循环的终止索引是length-1(range是左闭右开规则)。以输入[1,2,3]为例,length=2,循环range(l, 2)意味着:

  • 当l=0时,i只能取0、1,漏掉了i=2;
  • 当l=1时,i只能取1,漏掉了i=2;
    这直接导致最后一个元素从未参与交换,无法生成包含最后一个元素位置变化的排列。

同时,终止条件if l == length也存在逻辑偏差:当l等于len(nums)-1时,已经是最后一个元素的位置,此时应该直接添加当前列表状态到结果,但原循环没覆盖到这个位置的交换。

修正方案:

  • 去掉length变量,直接使用len(nums);
  • 循环范围改为range(l, len(nums));
  • 终止条件改为if l == len(nums),此时所有元素都已固定位置,添加结果即可。

修正后的完整代码

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        def dfs(nums, l):
            # base case:所有元素已固定位置
            if l == len(nums):
                res.append(nums.copy())
                return
            for i in range(l, len(nums)):
                # swap
                nums[l], nums[i] = nums[i], nums[l]
                dfs(nums, l+1)
                # backtrack
                nums[l], nums[i] = nums[i], nums[l]
        dfs(nums, 0)
        return res

内容的提问来源于stack exchange,提问作者peter todds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:37:07