想法是用一个数组记录所有数字是否出现,最后遍历这个数组。
cpp
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
bool num[100001];
memset(num,0,sizeof(num));
for(int i=0;i<nums.size();i++){
if(nums[i]<100001&&nums[i]>=0) num[nums[i]]=1;
}
for(int i=1;i<100001;i++) if(num[i]!=1) return i;
return 100001;
}
};
空间复杂度是O(100001),何尝不算是一种O(1)(?)
答案的两种方法都很巧妙。一种是上面这种的优化,即用原本的数组记录该数是否存在:
cpp
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<n;i++){
if(nums[i]<=0) nums[i]=n+1;
}
for(int i=0;i<n;i++){
if(abs(nums[i])<=n) nums[abs(nums[i])-1]=-abs(nums[abs(nums[i])-1]);
}
for(int i=0;i<n;i++){
if(nums[i]>0) return i+1;
}
return n+1;
}
};
若当前数(的绝对值)在[1,n]范围内,就将数对应于数组的位置变为负数(相当于记录该数存在,并不动这个位置原本的数),为了避免和原本的负数混淆,一开始就将非正数记为超过n的数。
还有一种方法是置换,若当前数在[1,n]内就将当前数和对应位置的数交换:
cpp
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
for(int i=0;i<nums.size();i++){
while(nums[i]<nums.size()&&nums[i]>0&&nums[i]!=nums[nums[i]-1]) swap(nums[i],nums[nums[i]-1]);
}
for(int i=0;i<nums.size();i++){
if(nums[i]!=i+1) return i+1;
}
return nums.size()+1;
}
};