LC.41. 缺失的第一个正数
因为要求时间复杂度且不额外开空间。所以考虑在原数组上操作。
1.原地哈希:将原数组的下标作为一个桶表示是否装有。
先预处理的元素全部置为,这样后面就不需要管了。
然后的元素对于的位置的元素置为负数即可。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for(auto &i:nums){
if(i<=0) i=n+1;
}
for(int i=0;i<n;i++){
int x=abs(nums[i]);
if(x<=n) nums[x-1]=-abs(nums[x-1]);
}
for(int i=0;i<n;i++) if(nums[i]>0) return i+1;
return n+1;
}
};
最后从前往后遍历第一个大于的元素下标即是答案。
2.置换法. 与第一种方法类似,也是当作一个桶处理,通过交换每轮使得桶是处理完的,最后从前往后遍历即可。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int 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]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
};
当然如果此题没有其他限制的话,还有排序法,利用各种数据结构解决。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int ans=1;
sort(nums.begin(),nums.end());
for(auto i:nums){
if(i==ans) ans++;
}
return ans;
}
};