缺失的正整數——不考算法,考腦力

缺失的正整數,我自己解出來了,和官方題解思路不一樣

題目描述:
給你一個未排序的整數數組,請你找出其中沒有出現的最小的正整數。

示例 1

輸入: [1,2,0]
輸出: 3



示例 2:

輸入: [3,4,-1,1]
輸出: 2



示例 3:

輸入: [7,8,9,11,12]
輸出: 1
 

提示:

你的算法的時間複雜度應爲O(n),並且只能使用常數級別的額外空間。

我的思路很直接,排序之後,重複的去重,剩下的第一個元素與1比較,第二個元素與2比較,第三個元素與3比較,依次類推,只要出現小於的情況,直接返回結果。

    public int firstMissingPositive(int[] nums) {
        if(null == nums) return 1;
        Arrays.sort(nums); // 排序
        int compare = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] <= 0) continue;
            if(i > 0 && nums[i-1] == nums[i]) continue; // 重複的數字直接略過
            compare++;
            if(compare < nums[i]) return compare;
        }
        // 數組中出現的正數,排序後恰好是遞增的,那就返回compare+1
        return compare+1;
    }


我的解法,沒什麼特別之處,時間複雜度是O(n),空間複雜度是常數級別的,符合題目要求。

下面看下官方的題解,思路很巧妙,我壓根就想不到。

若數組中有 n 個元素,且從1開始遞增的,那答案一定是n+1,否則答案一定是大於0小於n,
第一步,把數組中的元素,小於0的,大於n+1的都替換爲n+1;
第二步,對數組下標作文章,遍歷數組,比如第一個元素值是5,那就把第5個元素設置爲負數
第三步,再次遍歷數組,第一個大於0的數,說明沒有給它做標記的,即那個數字沒出現。

    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            if (nums[i] <= 0) {
                nums[i] = n + 1;
            }
        }
        for (int i = 0; i < n; ++i) {
            int num = Math.abs(nums[i]);
            if (num <= n) {
                nums[num - 1] = -Math.abs(nums[num - 1]);
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }

官方的題解確實很優雅,我真的想不到。我的解法,也還行,畢竟是符合題目要求的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章