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

LeetCode排列问题:JavaScript递归回溯函数返回空数组原因排查

回溯求解排列时返回空数组的原因与修复方案

问题核心原因

你的代码出现「控制台打印正确但最终返回空数组」的问题,根源在于数组引用的误用:

  1. 推入栈的引用而非副本
    当执行ans.push(stack)时,你推入的是stack数组的内存引用,而非当前栈内容的独立副本。后续递归中的stack.pop()会直接修改这个引用指向的数组内容。当整个回溯流程结束后,stack被清空回初始的空数组,ans里所有元素其实都是指向同一个空数组的引用,最终返回结果自然是[[]]。
    你控制台能打印正确结果,是因为打印操作发生在push之后、pop之前,此时栈内的排列内容还未被修改。

  2. 多余的ans.indexOf(stack)判断
    数组属于引用类型,indexOf比较的是引用地址是否相同。递归过程中stack始终是同一个数组引用,所以ans.indexOf(stack)永远返回-1,会重复推入同一个引用,但这不是返回空数组的核心原因,完全可以移除该判断(回溯逻辑本身不会生成重复排列)。

修复后的代码

只需要修改push操作,推入当前栈内容的副本即可:

/**
 * @param {number[]} nums
 * @return {number[][]} 
 */

var permute = function(nums) {
    let s = [], a = [];
    return findPerm(nums, s, a);
   
};

var findPerm = function(nums, stack, ans){
    if(nums.length === stack.length){
        ans.push([...stack]); // 推入栈的浅拷贝副本,避免引用共享
        console.log(ans);
        return; // 提前返回,减少不必要的循环
    }

    for(let num of nums){
        if(stack.indexOf(num) === -1){
            stack.push(num);
            findPerm(nums, stack, ans);
            stack.pop();
        }
    }
    return ans;
};

permute([1,2,3]);

补充说明

  • 除了[...stack],也可以用stack.slice()或Array.from(stack)来创建数组副本,效果一致。
  • 移除多余的indexOf判断后,代码逻辑更简洁,且不会影响结果正确性——因为回溯过程中每个排列只会被生成一次。

内容的提问来源于stack exchange,提问作者Will Sherman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:30:01