题目
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
说明:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-missing-positive
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
算法思路
- 在这个问题中我们可以巧妙地利用数组的 index 去求解问题。
- 首先若判断数组为空,直接返回最小正数 1。
- 遍历数组,若当前 nums[i] 大于 0 且 小于数组长度,我们就把他与nums[ nums[i] -1 ] 交换位置,这意味着,若 nums[i] 满足条件他将会被放置到对应数组 index 为 nums[i] -1 的位置,即:1,放置到 0位置,2 放置到 1位置(这是由于最小正数是从1开始的)。
- 完成上一步后,再一次遍历数组,若数组 下标 i+1 与 当前的 nums[i] 不相等,返回 nums[i]。
- 算法遍历两次,而最多交换 n 次位置,时间复杂度为 O(n)。
代码实现
/**
* @param {number[]} nums
* @return {number}
*/
var firstMissingPositive = function(nums) {
if(nums == false) return 1;
let len = nums.length;
for(let i = 0; i < len; i++){
while(nums[i] < len+1 && nums[i] > 0 && nums[i] != nums[nums[i]-1]){
let numsi = nums[i];
[nums[i],nums[numsi-1]] = [nums[numsi-1],nums[i]];
}
}
for(let i = 0; i < len+1; i++){
if(i+1 != nums[i]) return i+1;
}
};
值得注意的是,在这里我用了ES6的一个新方法交换数组元素的位置:[ nums[i], nums[j] ] = [ nums[j], nums[i] ]。在算法中由于是先给了 nums[i] ,nums[nums[i]-1] 赋值,而在交换中 nums[i] 的值会发生改变,倘若不先把 nums[i] 的值保存起来,在 while 中是会超时的!如果你也使用了这个方法,这里需要注意一下。