1. 程式人生 > 其它 >LeetCode448 找到所有陣列中消失的數字

LeetCode448 找到所有陣列中消失的數字

題目

給你一個含 n 個整數的陣列 nums ,其中 nums[i] 在區間 [1, n] 內。請你找出所有在 [1, n] 範圍內但沒有出現在 nums 中的數
字,並以陣列的形式返回結果。

示例 1: 
輸入:nums = [4,3,2,7,8,2,3,1]
輸出:[5,6]

示例 2: 
輸入:nums = [1,1]
輸出:[2]

提示: 
n == nums.length 
1 <= n <= 105 
1 <= nums[i] <= n 

進階:你能在不使用額外空間且時間複雜度為 O(n) 的情況下解決這個問題嗎? 你可以假定返回的陣列不算在額外空間內。 

方法

雜湊法

可以用hashSet儲存nums中存在的,然後遍歷1-n,未儲存在set的新增進返回的List中

  • 時間複雜度:O(n)
  • 空間複雜度:O(n)
class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        int n = nums.length;
        List<Integer> res = new ArrayList<>();
        Set<Integer> set = new HashSet<>();
        for(int num:nums){
            set.add(num);
        }
        for(int i=1;i<n+1;i++){
            if(!set.contains(i)){
                res.add(i);
            }
        }
        return res;
    }
}

陣列法

方法同雜湊法,可以用長度為n+1的陣列按下標儲存nums中存在的數字,然後遍歷陣列,未在陣列中標記的下標新增進返回的List中

  • 時間複雜度:O(n)
  • 空間複雜度:O(n)
class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        int n = nums.length;
        int[] arr = new int[n+1];
        List<Integer> res = new ArrayList<>();
        for(int num:nums){
            arr[num] = 1;
        }
        for(int i=1;i<n+1;i++){
            if(arr[i]<=0){
                res.add(i);
            }
        }
        return res;
    }
}

修改原陣列法

由題幹知,原陣列nums的長度也為n,我們可以在對應下標的數字做標記,如加上n來判斷當前下標是否有數字

  • 時間複雜度:O(n)
  • 空間複雜度:O(1)
class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        int n = nums.length;
        List<Integer> res = new ArrayList<>();
        for(int num:nums){
            nums[(num-1)%n] += n;  
        }
        for(int i=0;i<n;i++){
            if(nums[i]<=n){ //注意臨界情況nums[i]==n
                res.add(i+1);
            }
        }
        return res;
    }
}