1. 程式人生 > 實用技巧 >劍指OFFER03-陣列中重複的數字

劍指OFFER03-陣列中重複的數字

找出陣列中重複的數字。

在一個長度為 n 的陣列 nums 裡的所有數字都在 0~n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意一個重複的數字。

示例 1:

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

限制:

2 <= n <= 100000

方法一:

使用Set,遍歷陣列,如果Set中存在該元素就返回,否則新增到Set中

public int findRepeatNumber(int[] nums) {
        //方法一:用Set
  			//時間複雜度:O(n) 空間複雜度O(n)
        Set<Integer> set = new HashSet();
        for (int num : nums) {
            if (!set.add(num)){
                return num;
            }
        }
        return -1;
    }

方法二:

對陣列排序,相同的元素在相鄰位置,如果有則返回

public int findRepeatNumber(int[] nums) {
        //方法二:對陣列排序,相同的元素在相鄰位置,會修改原來的陣列
  			//時間複雜度:O(nlogn) 空間複雜度O(n)
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == nums[i + 1]) {
                return nums[i];
            }
        }
        return -1;
    }

方法三:

利用所有數字都在 0~n-1 的範圍內的條件,用一個額外的陣列,對每個值就在對應位置+1,當>1的時候返回

public int findRepeatNumber(int[] nums) {
        //方法三:利用所有數字都在 0~n-1 的範圍內的條件,用一個額外的陣列,對每個值就在對應位置+1,當>1的時候返回
        int length = nums.length;
        int[] temp = new int[length];
        for (int i = 0; i < length; i++) {
            //對應位置+1
            temp[nums[i]]++;
            //如果大於1,返回
            if (temp[nums[i]] > 1) {
                return nums[i];
            }
        }
        return -1;
    }

方法四:

將對應的數值放入陣列中的對應位置,如果有重複的返回

public int findRepeatNumber(int[] nums) {
        //方法四:將對應的數值放入陣列中的對應位置
        for (int i = 0; i < nums.length; i++) {
            //如果位置正確,繼續
            if (nums[i]== i){
                continue;
            }
            //如果重複,返回
            if (nums[i]==nums[nums[i]]){
                return nums[i];
            }
            //交換
            int temp = nums[nums[i]];
            nums[nums[i]] = nums[i];
            nums[i] = temp;
            //交換之後需要原地比較一次
            i--;
        }
        return -1;
}