1.題目
給定一個未排序的整數數組,找出其中沒有出現的最小的正整數。
示例 1:
輸入: [1,2,0]
輸出: 3
示例 2:
輸入: [3,4,-1,1]
輸出: 2
示例 3:
輸入: [7,8,9,11,12]
輸出: 1
你的算法的時間複雜度應爲O(n),並且只能使用常數級別的空間。
2. 思路
其實就是在滿足你的算法的時間複雜度應爲O(n),並且只能使用常數級別的空間。
的條件下實現一種排序算法
2.1 而且大於數組長度+1的數肯定不在考慮範圍內,如
1,4,3,2 最小值可能爲4+1
但是不可能爲5+1,比如
1,5,3,2 最小值 ( 肯定在小於等於數組長度的值裏面)+1
比如圖片中的,大於數組長度的肯定不是
public static int firstMissingPositive(int[] nums) {
if (nums == null || nums.length == 0) return 1;
int len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] == i + 1) continue;
while (nums[i] >= 1 && nums[i] <= len) {
int target = nums[i] - 1;
if (nums[i] == i + 1 || nums[target] == nums[i]) break;
//swap
int tmp = nums[i];
nums[i] = nums[target];
nums[target] = tmp;
}
}
for (int i = 0; i < len; i++) {
if (nums[i] != i + 1) return i + 1;
}
return len + 1;
}
這樣的算法,無論怎麼樣,都會把最小的放在前面,最大的在後面,比如我們給一個數組
int arr[] = new int[]{11, 3, 5, 2, 4, 1};
每次運行交換的結果是這樣的
11 ,5 ,3 ,2 ,4 ,1
11 ,4 ,3 ,2 ,5 ,1
11 ,2 ,3 ,4 ,5 ,1
1 ,2 ,3 ,4 ,5 ,11
再比如我們給一個順序的數組
int arr2[] = new int[]{1, 2, 5, 7, 8, 10};
每次運行的結果是:
1 ,2 ,8 ,7 ,5 ,10
其實發現就交換了一次,而交換的結果就是當前的位置,num[2]=8大於len停止交換
來個複雜點的,12個
int arr3[] = new int[]{1, 2, 3, 5, 8, 10, 3, 4, 5, 3, 6, 22};
交換的結果
1 ,2 ,3 ,8 ,5 ,10 ,3 ,4 ,5 ,3 ,6 ,22 ,
1 ,2 ,3 ,4 ,5 ,10 ,3 ,8 ,5 ,3 ,6 ,22 ,
1 ,2 ,3 ,4 ,5 ,3 ,3 ,8 ,5 ,10 ,6 ,22 ,
1 ,2 ,3 ,4 ,5 ,6 ,3 ,8 ,5 ,10 ,3 ,22 ,
3. 效率
執行用時 :
1 ms, 在所有 Java 提交中擊敗了99.54%的用戶
內存消耗 :34.9 MB, 在所有 Java 提交中擊敗了85.89%的用戶