1、問題描述
給定一個無序數組,求數組中缺失的第一個正整數。
示例1:
輸入:[1,2,3,4]
輸出:5
示例2:
輸入:[-1, 2, 5, 3]
輸出:1
示例3:
輸入:[5,7,8,9]
輸出:1
2、解題思路
分析:最小的正整數爲1,所以可以查找數組,看1是否存在;如果存在,則看2是否存在於數組中;如果存在,再看3是否存在於數組中;一直循環下去,直到不存在於數組中,那麼此時就是缺失的最小正整數。
那麼,需要查找的正整數最大爲多少呢?假設數組的長度爲,那麼
(1)如果都出現在了數組中,那麼最小的沒有出現的最小正整數爲;
(2)如果出現在了數組中,而()沒出現在數組中,那麼最小的沒有出現的最小正整數爲;
由上述分析可知,除第一種情況外,其他的缺失的最小正整數一定存在於內,因此可以使用以下幾種方法:
方法1:使用一個長爲的數組作爲哈希表來記錄中的每個數是否存在於數組中,標記數組下標所對應的元素如果大於0,則代表表示正整數存在於數組中,否則不存在。順序掃描數組並填充標記數組,最後再看標記數組中那個位置的值爲0,缺失的第一個整數即爲該位置下標+1;如果不存在爲0的位置,則缺失的整數數爲。
方法2:實際上,我們並不需要使用一個額外的標記數組,由於除第一種情況在,缺失的整數正整數一定存在於,因此可以利用數組本身作爲哈希表。我們把每個映射到的位置,具體地,
#順序掃描數組:
*如果當前元素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;
}
};