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

LeetCode三数之和代码疑问:hasSimularArray的return未正常退出?

3Sum问题中hasSimularArray函数return表现异常的原因

你在实现3Sum问题时,发现调用hasSimularArray函数时,感觉函数内的return true没有正常终止执行,像递归一样持续运行。但单独测试hasSimularArray是正常的,调试也没找到线索。

你的代码如下:

function threeSum(nums: number[]): number[][] {
  const tripletsResult = [];

  nums.sort((a, b) => a - b);

  for (let i = 0; i < nums.length - 2; i++) {
    let j = i + 1;
    let k = nums.length - 1;
    while (j < k) {
      const possibleResultEl = [nums[i], nums[j], nums[k]];
      const threeNumsSum = nums[i] + nums[j] + nums[k];
      if (threeNumsSum === 0) {
        const hasVal = hasSimularArray(tripletsResult, possibleResultEl);
        if (!hasVal) {
          tripletsResult.push(possibleResultEl);
        }
      } else if (threeNumsSum < 0) {
        j++;
      } else {
        k--;
      }
    }
  }

  return tripletsResult;
}

function hasSimularArray(mainArr: number[][], searchedArr: number[]) {
  if (mainArr.length === 0) {
    return false;
  }

  const searchArrayStr = JSON.stringify([...searchedArr].sort());
  for (let el of mainArr) {
    const elArrayStr = JSON.stringify([...el].sort());
    if (elArrayStr === searchArrayStr) {
      return true;
    }
  }
  return false;
}
console.log(threeSum([0, 3, 0, 1, 1, -1, -5, -5, 3, -3, -3, 0]));

问题根源

hasSimularArray函数本身没有问题,它的return语句完全正常——只要找到匹配的数组,就会立即终止函数并返回true。你看到的"持续运行"现象,是threeSum的循环逻辑缺陷导致的:

  • 虽然你对nums做了排序,但没有跳过重复的nums[i]。比如当nums[i]和前一个元素相同时,继续处理会生成完全相同的三元组,导致反复调用hasSimularArray检查重复。
  • 找到和为0的三元组后,也没有跳过j和k指向的重复元素,这会让while循环继续生成相同的三元组,再次触发hasSimularArray的调用。

这些重复的调用让你误以为是hasSimularArray没有终止,实际上每次调用都正常结束了,只是被反复触发而已。

修复方案

修改threeSum的循环逻辑,跳过重复元素,同时可以直接去掉效率低下的hasSimularArray函数:

function threeSum(nums: number[]): number[][] {
  const tripletsResult = [];
  nums.sort((a, b) => a - b);

  for (let i = 0; i < nums.length - 2; i++) {
    // 跳过重复的基准元素
    if (i > 0 && nums[i] === nums[i - 1]) continue;
    let j = i + 1;
    let k = nums.length - 1;
    while (j < k) {
      const sum = nums[i] + nums[j] + nums[k];
      if (sum === 0) {
        tripletsResult.push([nums[i], nums[j], nums[k]]);
        // 跳过j指向的重复元素
        while (j < k && nums[j] === nums[j + 1]) j++;
        // 跳过k指向的重复元素
        while (j < k && nums[k] === nums[k - 1]) k--;
        // 移动指针继续寻找
        j++;
        k--;
      } else if (sum < 0) {
        j++;
      } else {
        k--;
      }
    }
  }
  return tripletsResult;
}

console.log(threeSum([0, 3, 0, 1, 1, -1, -5, -5, 3, -3, -3, 0]));

修改说明

  • 循环i时,跳过和前一个元素相同的值,避免重复处理同一基准的三元组。
  • 找到和为0的三元组后,跳过j和k的重复元素,确保不会生成重复的结果。
  • 去掉hasSimularArray函数,既解决了你的困惑,又大幅提升了代码性能(原方法用JSON.stringify做重复检查,时间复杂度极高)。

内容的提问来源于stack exchange,提问作者Mini elephant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:06:19