-
原地哈希:
- 遍历数组,对于每个数字
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 = 0:
nums[0]是3,它在[1, n]范围内,并且nums[3-1]不是3,所以交换nums[0]和nums[2]。- 交换后数组变为:
[-1, 4, 3, 1]
- 交换后数组变为:
-
i = 0:继续检查
nums[0],现在是-1,不在[1, n]范围内,不做处理,继续下一个。 -
i = 1:
nums[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 = 2:
nums[2]是3,在正确的位置,不做处理。 -
i = 3:
nums[3]是4,在正确的位置,不做处理。