leetcode - [哈希表] - 數組中缺失的第一個正整數(41)

1、問題描述

給定一個無序數組,求數組中缺失的第一個正整數。
示例1:

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

示例2:

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

示例3:

輸入:[5,7,8,9]
輸出:1

2、解題思路

分析:最小的正整數爲1,所以可以查找數組,看1是否存在;如果存在,則看2是否存在於數組中;如果存在,再看3是否存在於數組中;一直循環下去,直到ii不存在於數組中,那麼此時ii就是缺失的最小正整數。

那麼,需要查找的正整數ii最大爲多少呢?假設數組的長度爲lenlen,那麼
(1)如果1,2,...,len1,2,...,len都出現在了數組中,那麼最小的沒有出現的最小正整數爲len+1len+1
(2)如果1,2,...,i11,2,...,i-1出現在了數組中,而iii[1,len]i\in[1,len])沒出現在數組中,那麼最小的沒有出現的最小正整數爲ii
由上述分析可知,除第一種情況外,其他的缺失的最小正整數一定存在於[1,len][1,len]內,因此可以使用以下幾種方法:
方法1:使用一個長爲lenlen的數組作爲哈希表來記錄1,2,...,len1,2,...,len中的每個數是否存在於數組中,標記數組下標ii所對應的元素如果大於0,則代表表示正整數i+1i+1存在於數組中,否則不存在。順序掃描數組並填充標記數組,最後再看標記數組中那個位置的值爲0,缺失的第一個整數即爲該位置下標+1;如果不存在爲0的位置,則缺失的整數數爲len+1len+1
方法2:實際上,我們並不需要使用一個額外的標記數組,由於除第一種情況在,缺失的整數正整數一定存在於[1,len][1,len],因此可以利用數組本身作爲哈希表。我們把每個i[1,len]i\in[1,len]映射到i1i-1的位置,具體地,

#順序掃描數組:
	*如果當前元素nums[i]屬於[1,len],則把它交換到它本該處於的位置num[i]-1,即位置i上的元素和位置nums[i] - 1上的元素交換,但如果兩個位置的元素相等,則不必進行交換;
	*如果交換完後,位置i上的元素仍然屬於[1,len],則再次進行交換;
#再次掃描數組,如果下標i位置的元素nums[i]不等於i+1,則i+1爲缺失的最小正整數,否則爲len+1

3、代碼實現

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int len = nums.size();
        if(len == 0){
            return 1;
        }
        for(int i = 0; i < len; ++i){
            while(nums[i] >= 1 && nums[i] <= len && nums[i] != nums[nums[i] - 1]){
                swap(nums, i, nums[i] - 1);
            }
        }
        for(int j = 0; j < len; ++j){
            if(nums[j] != j + 1){
                return j + 1;
            }
        }
        return len + 1;
        
    }
    void swap(vector<int>& nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章