【LeetCode Top 100】448. Find All Numbers Disappeared in an Array【Easy】【JAVA】

1. 題目

在這裏插入圖片描述

2. 題意

題目很好理解,需要注意的是範圍是[1,n],跟數組下標範圍[0,n-1]剛好相差了1。

3. 方法一

3.1 思路

由於數字範圍剛好大於數組下標範圍1,最簡單的思路,構造一個大小爲n的boolean類型的數組boolean[] isContainisContain[i]代表數組中是否包含了數字i+1。從頭到尾遍歷整個數組,對每個值val,將isContian[val-1]置爲true,即標記出現的值。再從頭到尾遍歷isContain數組,找出哪些下標爲false,推斷出哪些數字沒有出現在[1,n]的範圍中。
該方法的時間複雜度爲O(n),需要遍歷2次數組,空間複雜度爲O(n),爲boolean數組的開銷。

3.2 代碼

    public List<Integer> findDisappearedNumbers(int[] nums) {
        boolean[] isContain = new boolean[nums.length];
        for (int num : nums
                ) {
            isContain[num - 1] = true;
        }
        
        List<Integer> response = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            if (!isContain[i]) {
                response.add(i + 1);
            }
        }
        return response;
    }

3.3 運行結果

在這裏插入圖片描述

4. 方法二

4.1 思路

對於方法一,運行速度快,但沒有實現空間複雜度爲O(1),接下來考慮保持時間複雜度不變O(n),降低空間複雜度。
考慮方法一,我們的空間開銷是在boolean數組上,它的作用在於記錄哪些值已經出現過了,因此我們考慮能否使原數組也有記錄值是否出現的能力。聯想到一個簡單的方法,正負值,我們可以當某個值出現時,我們修改原數組的值的正負,來標記該值是否已經出現。
例如對於[3,3,2]數組,我們從頭遍歷,第一個數字的絕對值爲3,將3-1=2下標對應的值修改爲負,原數組變爲[3,3,-2],對於第二個數,同樣絕對值爲3,將3-1=2下標對應的值修改爲負,原數組爲[3,3,-2],遍歷第三個數,絕對值爲2,將2-1=1下標對應的值改爲負,原數組爲[3,-3,-2],從頭遍歷數組,發現只有下標爲0的數爲正,即該數組中不包含0+1=1,不包含1這個數。

4.2 代碼

    public List<Integer> findDisappearedNumbers1(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            int temp = Math.abs(nums[i]) - 1;
            if (nums[temp] > 0) {
                nums[temp] = -nums[temp];
            }
        }
        List<Integer> response = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                response.add(i + 1);
            }
        }
        return response;
    }

4.3 運行結果

在這裏插入圖片描述

5. 相關鏈接

本題代碼的github鏈接
其他 Top 100 Liked Questions 題目

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