1. 程式人生 > >41. 缺失的第一個正數

41. 缺失的第一個正數

給定一個未排序的整數陣列,找出其中沒有出現的最小的正整數。

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