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

65 阅读1分钟

leetcode-41.png

这一题其实思路挺多的,但是题目条件有限制,时间复杂度要求在O(n)内,常数的空间。
如果没有这些要求,其实可以用排序来解。或者用hash也能解。

这里解法的重点就在于swap,如何swap呢?
将当前的元素nums[i]放在数组的第i位上
nums[1] = 3,那么nums[1]就应该放在第3个元素的地方,也就是index = 2的地方
也就是下面这种样子

[x,x,3,x,x,x]
var firstMissingPositive = function (nums) {
    let len = nums.length
    for (let i = 0; i < len; ++i) {
        // 将当前数字 nums[i] 比如说 3 放在数组的第三个元素的地方
        // 也就是 num[2] ===> nums[3-1] ===> nums[nums[i] - 1]
        while (nums[i] > 0 && nums[i] <= len && nums[nums[i] - 1] !== nums[i]) {
            let currentIndex = nums[i] - 1;
            // swap 交换
            [nums[currentIndex], nums[i]] = [nums[i], nums[currentIndex]]
        }
    }
    // 经过上面的操作,数字就会放在对应的地方,也就是 3,就会放在 第三个元素的地方
    // 那么就是 3 会放在 索引为 2 的地方
    for (let i = 0; i < len; ++i) {
        // 找出不对应的数字,进行返回即可
        if (nums[i] !== i + 1) {
            return i + 1
        }
    }
    // 如果没找到,说明数字都进行了完全的交换,就直接返回
    // 对于这个测试用例来说 [1,2,3,4,5],都在对应的位置上
    // 那么就直接返回第 6 个元素即可,也就是 len = 5, return 5 + 1
    return len + 1
};