剑指 Offer 03. 数组中重复的数字

用时4分02秒,用哈希表做的,显然不够优化:

public int findRepeatNumber(int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        for (int num : nums) {
            if (!map.containsKey(num)) {
                map.put(num, 1);
            } else {
                return num;
            }
        }
        return -1;
    }


 方法二:

考虑先排序再寻找:

public int findRepeatNumber(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        if(n<2) return -1;
        int j = 1;
        while(j<n){
            if(nums[j] == nums[j-1]){
                return nums[j];
            }else{
                j++;
            }
        }
        return -1;
    }

 性能有所提高,但是还有上升空间,应该怎么优化?


因为数组中的数字都在0~n-1的范围内,如果没有重复数字,则当数组排序之后,数字i出现在下标为i的位置。

由于数组中有重复的数字,有些位置可能存在多个数字,同时有些位置没有数字。

从头到尾扫描数组中的每个数字。当扫描下标为i的数字时,首先比较这个数字(用m表示)是不是等于i。如果是,接着扫描下一个数字;

如果不是,再拿它和第m个数字进行比较。

若它与第m个数字相等,则返回;

若不相等,就把第i个数字与第m个数字进行交换,把m放在属于它的位置上。

重复这个比较和交换过程,直到我们发现一个重复数字。

public int findRepeatNumber(int[] nums) {
        int n = nums.length;
        int i = 0;
        while(i<n){
            if(nums[i] == i){
                i++;
            }else{
                if(nums[i] == nums[nums[i]]){
                    return nums[i];
                }else{
                    int x = nums[i];
                    nums[i] = nums[x];
                    nums[x] = x;
                }
            }
        }
        return -1;
    }

我的前方是万里征途,星辰大海!!
原文地址:https://www.cnblogs.com/taoyuxin/p/13444473.html