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;
}
};