https://oj.leetcode.com/problems/first-missing-positive/數組
感受這題還蠻難的,O(n)的時間,常數大小的額外空間,這個要求仍是比較苛刻的spa
首先,數組應該是能夠修改的,不然恐怕無法作了,由於總要有一個地方來記憶一些信息,既然不給O(n)的額外的空間,只能在本地記憶了code
想法是:blog
從左到右掃描數組,把數字放到恰當的位置上(把K放到數組的A[K-1]中,放以前,要把A[K-1]記下來)leetcode
好比A[] = [3,4,-1,1],準備一個額外空間idx,get
掃描到3時,先把A[2]的值記入idx(爲3這個數騰出空間),而後把3放到A[2]it
而後就處理存儲在idx中的這個值,發現idx<=0,那麼不用管io
此時數組變成[3,4,3,1]class
而後掃描第二個位置,即A[1]=4循環
將A[3]的值記入idx,而後把4放入A[3]
當前狀態:idx=1,A[]=[3,4,3,4]
而後處理存儲在idx中的這個值,idx=1,知足idx>0 && idx <= sizeOfArray(對於1到sizeOfArray之間的數字,都是要處理的,由於結果就是這中間的某個數)
把A[0]的值記入idx,把當前的idx記入A[idx-1],即把1記入A[0]
當前狀態:idx=3,A[]=[1,4,3,4]
而後又是要處理存儲在idx中的這個值,此時idx=3,發現A[2]==3,不須要繼續處理了(由於繼續下去就是無限循環)
而後掃描第三個位置,一樣發現A[2]==3,不須要處理
而後掃描第四個位置,發現A[3]==4,不須要處理
注意到咱們在處理的過程當中,沒有丟失1到sizeOfArray之間的任何一個數字,因此能夠保證結果的正確性
而後從左到右第二次掃描這個數組,這個時候,有以下條件成立:對出如今原數組中的1到sizeOfArray之間的任何一個數字K,它確定被放到了A[K-1]
因此掃描的時候,若是遇到A[i]!=i+1,那麼說明i+1在原數組中不存在,結果就是i+1
若是A[i]==i+1對i從0到sizeOfArray-1都成立,結果就是sizeOfArray+1
//result must be in [1..n] class Solution { public: int firstMissingPositive(int A[], int n) { for(int i = 0; i < n; i++){ if(A[i] == i+1) continue; //a[i]!=i+1 int idx = A[i]; while(idx > 0 && idx <= n){ if(A[idx-1] == idx) break; int tmp = A[idx-1]; A[idx-1] = idx; idx = tmp; } } for(int i = 0; i < n; i++){ if(A[i] != i+1){ return i+1; } } return n+1; } };