代碼題(40)— 缺失的第一個正數、缺失數字


1、41. 缺失的第一個正數

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

示例 1:

輸入: [1,2,0]
輸出: 3

示例 2:

輸入: [3,4,-1,1]
輸出: 2

示例 3:

輸入: [7,8,9,11,12]
輸出: 1

思路:交換數組元素。使得數組中第i位存放數值(i+1)。

最后遍歷數組,尋找第一個不符合此要求的元素,返回其下標。整個過程須要遍歷兩次數組,復雜度為O(n)。

下圖以題目中給出的第二個樣例為例,解說操作過程。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        if(nums.empty())
            return 1;
        int n = nums.size();

        for(int i=0;i<n;++i)
        {
            if(nums[i] <= 0)
                continue;
            //思路:交換數組元素。使得數組中第i位存放數值(i+1)。
            //假設交換的數據還是大於0且<i+1,且數據不相等,則放在合適的位置,避免死循環
            while(nums[i]>0 && nums[i]<=i+1 && nums[i] != nums[nums[i]-1])
                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;
    }
};

 

2、268. 缺失數字

給定一個包含 0, 1, 2, ..., n 中 n 個數的序列,找出 0 .. n 中沒有出現在序列中的那個數。

示例 1:

輸入: [3,0,1]
輸出: 2

示例 2:

輸入: [9,6,4,2,3,5,7,0,1]
輸出: 8

  這道題還可以用二分查找法來做,我們首先要對數組排序,然后我們用二分查找法算出中間元素的下標,然后用元素值和下標值之間做對比,如果元素值大於下標值,則說明缺失的數字在左邊,此時將right賦為mid,反之則將left賦為mid+1。那么看到這里,作為讀者的你可能會提出,排序的時間復雜度都不止O(n),何必要多此一舉用二分查找,還不如用上面兩種方法呢。對,你說的沒錯,但是在面試的時候,有可能人家給你的數組就是排好序的,那么此時用二分查找法肯定要優於上面兩種方法。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        if(nums.empty())
            return -1;
        int n = nums.size();
        sort(nums.begin(),nums.end());
        
        int left = 0,right = n;
        while(left<right)
        {
            int mid = (left+right)/2;
            if(nums[mid] == mid)
                left = mid+1;
            else 
                right = mid;
        }
        return right;
    }
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM