給定一個未排序的整數數組,找出其中沒有出現的最小的正整數。算法
示例 1:數組
輸入: [1,2,0]
輸出: 3blog
示例 2:排序
輸入: [3,4,-1,1]
輸出: 2索引
示例 3:it
輸入: [7,8,9,11,12]
輸出: 1class
你的算法的時間複雜度應爲O(n),而且只能使用常數級別的空間O(1)。方法
這道題若是不要求時間複雜度爲O(n)和空間O(1)的話,其實很簡單的,能夠先對數組作一個排序,而後從小到大的找第一個缺失的正整數。可是排序的時間複雜度至少也是O(nlogn)。因此不能用排序的方法來進行查找。di
對一個數組而言,其實最小的值排列就是[1…..length]的值,這個怎麼理解呢。好比長度爲4的數組,那麼這個數組最小整數排列就是1,2,3,4。也就是長度爲4的數組能容納的最小數就是1,2,3,4。那麼對於任意一個長度爲4的數組,缺失的最小正整數就必定在[1-length]之間的值。對於索引而言就是最小正整數必定存在於[1-index+1]的範圍。時間
既然最小的值和數組的索引有如此的關係,那麼咱們就能夠藉助索引的方法,將各個值放入到其對應的索引中去。好比i=4, num[i]=3, 那麼咱們就該把3和i=2的值進行互換。至於值超出數組長度或者負數,則不用去管。這樣能保證在數組長度範圍內的數都在起索引的位置上。變相起到了排序的功能。
用一個長度爲5的數組來看下:
-1, 3, 5, 2, 7
Step1: i=0; num[i]=-1。不處理. i++
Step2: i=1; num[i]=3<5, 所以放入對應的索引位置,也就是3-1=2, 將num[1]和num[2]對換。數組變成-1,5,3,2,7.
Step3:i=2;num[i]=3 正好對應其索引位置,不處理,i++;
Step4:i=3 num[3]=2<5 放入對應的索引位置,也就是2-1=1, 將num[3]和num[1]對換。
數組變成-1,2,3,5,7
Step5:i=4 num[4]=7>5 不處理
最終的數組變成-1,2,3,5,7。 那麼從數組開始判斷,看下num[i]是不是和i+1相等。若是不是,則缺失的最小正整數就是i+1。 上面的數組明顯就能夠得出缺失的最小正整數就是0+1=1。
代碼以下:
int firstMissingPositive(int a[], int len) { int i,temp; i = 0; while(i<len) { if (a[i] < 0 || a[i] > len || a[a[i] - 1] == a[i]) { i++; } else { temp = a[a[i] - 1]; a[a[i] - 1] = a[i]; a[i] = temp; i++; } } for (i = 0; i < len; i++) { if (a[i] != i + 1) return i + 1; } return -1; }