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

LeetCode问题:寻找缺失的最小正整数(代码逻辑错误排查)

问题分析与修复

先说说你代码的问题:当输入[1]时,循环里只会执行continue跳过,循环结束后没有任何返回语句,导致函数返回undefined。这是因为你处理i=0的情况时,只判断了arr[i] == i+1就跳过,但没处理所有正整数连续时的返回逻辑。

先修复当前代码的bug

把循环结束后的返回逻辑移到循环外面,这样像[1]、[1,2,3]这类所有正整数连续的情况,循环结束后就能返回正确结果:

var firstMissingPositive = function(nums) {
  nums.sort(compare);
  var arr = [];

  for (let i = 0; i < nums.length; i++) {
    if (nums[i] > 0)
      arr.push(nums[i]);
  }

  if (arr.length === 0)
    return 1;
  
  // 先检查第一个正整数是不是1
  if (arr[0] !== 1) {
    return 1;
  }

  // 遍历检查连续的正整数,同时跳过重复值
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] === arr[i-1]) {
      continue;
    }
    if (arr[i] !== arr[i-1] + 1) {
      return arr[i-1] + 1;
    }
  }

  // 所有正整数都连续,返回最后一个数+1
  return arr[arr.length - 1] + 1;
};

function compare(a, b) {
  return a - b;
}

注意:当前解法不符合线性时间+常数空间要求

你原本的需求是线性时间(O(n))和常数空间(O(1)),但上面的代码用了sort(时间复杂度O(nlogn)),还额外创建了数组arr(空间复杂度O(n)),不符合要求。下面给你符合要求的最优解法:

var firstMissingPositive = function(nums) {
  const n = nums.length;

  // 第一步:把所有不在[1,n]范围内的数替换成n+1
  for (let i = 0; i < n; i++) {
    if (nums[i] <= 0 || nums[i] > n) {
      nums[i] = n + 1;
    }
  }

  // 第二步:用数组本身当哈希表,标记出现过的正整数
  for (let i = 0; i < n; i++) {
    const num = Math.abs(nums[i]);
    if (num <= n) {
      // 把对应索引的数改成负数,代表这个数已经出现过
      nums[num - 1] = -Math.abs(nums[num - 1]);
    }
  }

  // 第三步:找到第一个正数的索引,对应的就是缺失的最小正整数
  for (let i = 0; i < n; i++) {
    if (nums[i] > 0) {
      return i + 1;
    }
  }

  // 如果所有数都是负数,说明1~n都出现了,返回n+1
  return n + 1;
};

这个解法的核心思路是利用数组的索引作为哈希键,用元素的正负来标记该数是否出现过,全程只遍历数组三次,没有额外开辟空间,完全符合线性时间和常数空间的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:40:10