【leetcode】41. 缺失的第一个正数

124 阅读1分钟

leetcode-41.png

  • 原地哈希

    • 遍历数组,对于每个数字 nums[i],如果它在 [1, n] 范围内(其中 n 是数组长度),并且它不在正确的位置上(即 nums[i] 不是 i+1),那么我们尝试将 nums[i] 放到它正确的位置上,即 nums[i] 放到 nums[nums[i] - 1] 上。
  • 查找第一个缺失的正数

    • 再次遍历数组,如果发现 nums[i] != i+1,则 i+1 即为缺失的第一个正整数。
  • 特殊情况

    • 如果遍历结束后所有的数字都在正确的位置上,那么缺失的最小正整数就是 n+1
var firstMissingPositive = function (nums) {
    let n = nums.length
    for (let i = 0; i < n; ++i) {
        while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) {
            // swap
            [nums[nums[i] - 1], nums[i]] = [nums[i], nums[nums[i] - 1]]
        }
    }
    for (let i = 0; i < n; ++i) {
        if (nums[i] !== i + 1) return i + 1
    }
    return n + 1
};

测试用例

考虑输入数组为 [3, 4, -1, 1]

第一遍遍历

  • i = 0nums[0] 是 3,它在 [1, n] 范围内,并且 nums[3-1] 不是 3,所以交换 nums[0] 和 nums[2]

    • 交换后数组变为:[-1, 4, 3, 1]
  • i = 0:继续检查 nums[0],现在是 -1,不在 [1, n] 范围内,不做处理,继续下一个。

  • i = 1nums[1] 是 4,在 [1, n] 范围内,并且 nums[4-1] 不是 4,所以交换 nums[1] 和 nums[3]

    • 交换后数组变为:[-1, 1, 3, 4]
  • i = 1:继续检查 nums[1],现在是 1,它应该放在索引 0 处,交换 nums[1] 和 nums[0]

    • 交换后数组变为:[1, -1, 3, 4]
  • i = 2nums[2] 是 3,在正确的位置,不做处理。

  • i = 3nums[3] 是 4,在正确的位置,不做处理。