[array] leetcode - 41. First Missing Positive - Hard
leetcode - 41. First Missing Positive - Hard
descrition
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.
Your algorithm should run in O(n) time and uses constant space.
解析
註意題目的要求,時間復雜度: O(n)。如果沒有時間復雜度的現在,我們可以對數組進行排序,並檢查順序數組中 positive 數的缺失情況即可,時間復雜度為O(nlog(n))。
在有時間復雜度限制的情況下,我們需要進一步分析題目的特點。
- 此處還需要註意的是,positive 是指那些大於 0 的數。
- 要找到第一個缺失的正整數(所謂的第一個正整數,是指從 1 開始計數,第一個缺失的正整數)
基本原理:對於 k 個正整數(允許重復),第一個缺失的值必然在區間 [1,k+1] 內。可以想象成,將 k 個球放到 k+1 個箱子裏,那麽必然有至少有一個箱子是空的。
對於長度為 n 的整型數組 arry[],假設正整數的個數為 k 個,k<=n,那麽缺失的值必然在區間 [1,k+1]內,我們可以將區間映射到 [0,k](當 k=n 時,區間為[0,n-1])。
(輔助理解:[1,k+1] 可以看成是從 1 開始順序編號的箱子,直到 k+1,我們現在有 k 個正整數,正整數的數值表示起要放到幾號桶,因為我們最多只有 k 個正整數,那麽必然至少有一個桶時空的)
根據以上分析,對於任意正整數 1<=arry[i]<=n,我們可以從左邊到右(從編號1開始到k)將其放到 arry[i]-1 的位置。滿足 1<=arry[i]<=n 條件的數最多有 n 個。最後檢查,如果存在 arry[i] != i+1 ,那麽 i+1 就是缺失的第一個正整數,最極端的情況是 n 個數都滿足 arry[i] == i+1,此時第一個缺失的正整數為 n + 1。(註意!!從左往右遍歷)
具體實現如代碼所示。註意,滿足 1<=arry[i]<=n 條件的正整數有可能存在重復,因此需要檢查即將要放置的目標位置是否已經滿足條件,如果不滿足條件才能放置。
code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution{
public:
// time-O(n), space-O(1)
int firstMissingPositive(vector<int>& nums){
int n = nums.size();
// put the element to the right place
// i must be increased from 0 to n, becasue we need to satisfy the lower number first
for(int i=0; i<n; i++){
while(nums[i] > 0 && nums[i] <= n && nums[nums[i]-1] != nums[i]){
// note: nums[nums[i]-1] != nums[i] indicate the place nums[nums[i]-1] hasn‘t satisfied
// so we can place the nums[i] to nums[nums[i]-1]
swap(nums[i], nums[nums[i]-1]);
}
}
// find the first missing positive
for(int i=0; i<n; i++){
if(nums[i] != (i+1))
return i+1;
}
return n + 1;
}
};
int main()
{
return 0;
}
[array] leetcode - 41. First Missing Positive - Hard