力扣41. 缺失的第一個正數,一個很奇妙的排序算法

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的數肯定不在考慮範圍內,如

1432 最小值可能爲4+1
但是不可能爲5+1,比如
1532 最小值 ( 肯定在小於等於數組長度的值裏面)+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%的用戶
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章