题目描述
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
思路
刚开始看到这道题感觉很简单,直接排序,然后从前往后扫描跳过负数,然后开始扫描,找到第一个没有出现的正数即可。
运行速度很快,但是总感觉不是这么写的…
代码
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
int ans = 1;
for(int i = 0; i < n; i++){
while(i+1 < n && nums[i] == nums[i+1])
i++;
if(nums[i] <= 0)
continue;
if(nums[i] == ans )
ans++;
else
break;
}
return ans;
}
};
改进思路
于是看了一些别人的思路,找到了一个桶排序的方法,时间复杂度只有O(N)。
方法如下:
- 从后往前扫描一遍,跳过所有的负数,将数i放到索引为i-1的位置上,如果正数超出数组的长度可以不考虑。
- 再次从头往后扫描,找到第一个nums[i] != i+1即找到答案。
感觉算法比较高级,比前面的方法的时间复杂度要小,但是最后的运行结果显示却不如前面的方法的结果好,不明白为什么…T T
代码
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for(int i = 0; i < n;){
if(nums[i] <= 0 || nums[i] > n || nums[i] == i+1 ){
i++;
continue;
}
int tmp = nums[i];
if(tmp == nums[tmp-1]){
i++;
continue;
}
nums[i] = nums[tmp - 1];
nums[tmp - 1] = tmp;
}
int i;
for(i = 0; i < n; i++){
if(nums[i] != i+1)
return i+1;
}
return i+1;
}
};