Given an unsorted integer array, find the smallest missing positive integer.
Example 1:
Input: [1,2,0] Output: 3
Example 2:
Input: [3,4,-1,1] Output: 2
Example 3:
Input: [7,8,9,11,12] Output: 1
Note:
Your algorithm should run in O(n) time and uses constant extra space.
分析:缺失的第一个正数只有两种情况 1:[1, len]之间 ; 2:len+1
Solution 1 :若当前位置上没有被放置应该放置的数, 则不断让当前位置的数与该数该去的位置的数交换,直到索引index对应的第index+1个位置的数值为index+1。其中,所有被考察的数都应属于[ 1, len]的范围.
Point:
循环的终止条件是当前位置已经放置了应该放置的数;每轮循环的操作是一个当前位置的数该去的位置的数与当前数的交换
虽然循环的目的是希望最终该位置放置对应的数,但在多次交换过程中,也另所有交换经过此位置的数正确归位。
例如: 4 1 3 2 我们的目的是希望1位置放1 2 位置放2 3位置放3 4位置放4 在遍历处理第一个位置时,第一个位置并未存放期望的1 所以将经过此位置的4正确归位到位置4,同时将2换到此位置(依次,2归位,1归位,本位置处理完毕,开始处理下一个位置2.。。。)
Code:
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int len = nums.size();
for(int i=0; i < len; i++){
while(nums[nums[i]-1] != nums[i] && nums[i] > 0 && nums[i] <= len){
swap(nums[nums[i]-1], nums[i]);
}
}
for(int i=0; i < len; i++){
if(nums[i] != i+1){
return i+1;
}
}
return len+1;
}
};
Solution 2:若当前位置上没有被放置应该放的数并且该数该去的位置未放置该数(可重复?)实质上和Solution1一样,注意步长增量放置的位置。
Code:
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int len = nums.size();
for(int i=0; i < len; ){
if(nums[i] <= 0 || nums[i] > len){
i++;
}
else if(nums[i] != i+1 && nums[nums[i]-1] != nums[i]){
swap(nums[i], nums[nums[i]-1]);
}
else
i++;
}
for(int i=0; i < len; i++){
if(nums[i] != i+1){
return i+1;
}
}
return len+1;
}
};