leetcode之路(缺失的第一個正數)

leetcode之路(缺失的第一個正數)

題目:

給定一個未排序的整數數組,找出其中沒有出現的最小的正整數。
示例 1:
輸入: [1,2,0]
輸出: 3
示例 2:
輸入: [3,4,-1,1]
輸出: 2
示例 3:
輸入: [7,8,9,11,12]
輸出: 1
說明:
你的算法的時間複雜度應爲O(n),並且只能使用常數級別的空間。

“實現一個功能如果需要10分鐘,思考的時間是7分鐘”
思考過程
拿到題目最容易想到的方法是對數組先排序,然後從一往後找,就可以很輕鬆的找到缺失的正數。
**方法一:**使用sort()對數組進行排序,然後從1還是逐個找下一個正數,如果找到的結果大於應該出現的正數,說明該數即是所求。方法關鍵代碼:

int firstMissingPositive(vector<int>& nums) {
        int ret=1;
        if(nums.size()==0)
        return ret;
        sort(nums.begin(),nums.end());
        vector<int>::iterator iter=nums.begin();
        for(;iter!=nums.end();iter++){
            if(ret==*iter)
            ret++;
            else if(*iter>ret)
            break;
        }
        return ret;
    }

but題目要求中“你的算法的時間複雜度應爲O(n),並且只能使用常數級別的空間。”sort()函數的時間複雜度爲nlog2(n),顯然我們的代碼雖然可以求出題目的答案,但並不符合題目要求。於是就有了相對高級的方法二。
方法二: 方法二的思想與方法一無異,但是改進了一下排序的方法,我們使用交換位置的方法對原來的數組原地排序(當給我們的nums[0]是3時,我們可以讓nums[0]與num[2]交換這樣3就回到了正確的位置,直到nums[0]=1時再到nums[1]的值進行操作),根據題意我們只需對正數進行排序,但是有這麼幾種情況是我們無法找到正確的位置的:
1、nums[i]>nums.size(),或者nums[i]<1,這時的i-1下標越界,直接i++
2、nums[i]==nums[nums[i]-1],這個數對應位置上的數已經是正確的了,說明有重複數字,直接i++;
爲了方便理解,附上一個例子:當nums={3,-1,4,6,1}時,該算法的運行過程爲:排序
方法二的代碼如下:

class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
for(int i=0;i<nums.size();){
         if(nums[i]<=0||nums[i]>nums.size()||nums[i]==i+1||nums[i]==nums[nums[i]-1])
             i++;
         else{
             int tem;
             tem=nums[nums[i]-1];
             nums[nums[i]-1]=nums[i];
             nums[i]=tem;}
          }
          for(int i=0;i<nums.size();i++){
             if(nums[i]!=i+1)
             return i+1;
         }
         return nums.size()+1;}
  
};

提交結果

執行用時 :4 ms
, 在所有 C++ 提交中擊敗了86.60%的用戶
內存消耗 :8.6 MB
, 在所有 C++ 提交中擊敗了81.74%的用戶

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章