leetcode442. Find All Duplicates in an Array

題目要求

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:
Input:
[4,3,2,7,8,2,3,1]

Output:
[2,3]

存在一個整數數組,其中的所有元素都位於1~n之間,其中n是數組的長度。有的元素出現了一次,而有的元素出現了兩次。找到數組中所有出現兩次的數字。

思路一:交換

爲了在O(N)的時間內找到所有的出現兩次的數字,其核心要求在於用現有的數組記錄已經訪問過的元素,同時不會丟失尚未訪問過的元素。思路一採用交換的核心思想,即每次都將當前下標上的值和以該值爲下標的位置上的值進行交換,如果該值下標位置上的值和其相等,則說明該數字已經被遍歷過一遍了。

代碼如下:

    public List<Integer> findDuplicates(int[] nums) {
        int index = 0;
        List<Integer> result = new ArrayList<Integer>();
        while(index < nums.length) {
            int num = nums[index];
            if(num == 0){
                index++;
            }else if (nums[num-1] == num) {
                if(index != num-1){
                    result.add(num);
                    nums[index] = 0;
                }
                index++;
            }else{
                swap(index, num-1, nums);
            }
        }
        return result;
    }
    
    public void swap(int i, int j, int[] nums) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

思路二:取反

有沒有一種辦法在既保留當前位置上的值nums[i]的同時,又能夠用某種方式記錄i+1是否已經被訪問過了?可以通過取反的方法來記錄是否被訪問過這個情況。如果訪問到下標爲i的位置上的值,則去判斷nums[nums[i]-1]位置上的值是否爲負數,如果是,則說明num[i]出現了兩次,否則將nums[nums[i]-1]位置上的值取反保留。

代碼如下:

    public List<Integer> findDuplicates(int[] nums) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; ++i) {
            int index = Math.abs(nums[i])-1;
            if (nums[index] < 0)
                res.add(Math.abs(index+1));
            nums[index] = -nums[index];
        }
        return res;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章