41. 缺失的第一個正數
阿新 • • 發佈:2018-12-19
給定一個未排序的整數陣列,找出其中沒有出現的最小的正整數。
示例 1:
輸入: [1,2,0] 輸出: 3 示例 2:
輸入: [3,4,-1,1] 輸出: 2 示例 3:
輸入: [7,8,9,11,12] 輸出: 1 說明:
你的演算法的時間複雜度應為O(n),並且只能使用常數級別的空間。
思路一:用集合。我們把給定陣列的正整數都插入到集合裡,並且在插入的同時記錄最大值。之後從1開始遍歷到最大值,若遍歷到某個值是該值在集合中不存在,就返回該值,如果都存在,那麼最後返回最大值+1.這種解法並不滿足常熟級別的空間。
class Solution {
public:
int firstMissingPositive (vector<int>& nums) {
unordered_set<int> s;
int maxNum = 0;
for(int i = 0; i < nums.size(); i++) {
if(nums[i] <= 0) {
continue;
}
s.insert(nums[i]);
maxNum = max(maxNum, nums[i]);
}
for (int i = 1; i <= maxNum; i++) {
if(!s.count(i)) {
return i;
}
}
return maxNum + 1;
}
};
思路二:原地改變陣列。 我們能不能想辦法讓nums[i]所表示的值為i+1,這樣的話之後遍歷陣列,只需要找到與下標不符的位置即可。那麼如何讓nums[i]的值為i+1呢?我們遍歷給定陣列,當發現nums[i]>0,nums[i]<=n,並且nums[nums[i]-1]!=nums[i]的時候,我們用while迴圈交換nums[nums[i]-1]和nums[i],直到位置正確。你們看看這一步效果是什麼。
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[i], nums[nums[i] - 1]);
}
}
for(int i = 0; i < n; i++) {
if(nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
};