剑指offer(一)

62 阅读1分钟

3. 重复数问题

image.png

我的解法:

class Solution {
    public int findRepeatNumber(int[] nums) {
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[i]==nums[j]){
                    return nums[i];
                }
            }
        }
        return -1;
    }
}

image.png 缺点:暴力、不够优雅

利用Set的不可重复性

class Solution {
    public int findRepeatNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            if(!set.add(nums[i])){
                return nums[i];
            }
        }
        return -1;
    }
}

image.png

额,时间上去了,内存下来了

书解:

书上的解法

image.png

高,实在是高,优雅,实在是优雅!

这里写的时候还要注意就是,避免1,1,2,3,4,5这种情况,会导致一直while下去,可以在每次while的时候判断一下nums[i]nums[nums[i]]如果是一样的直接找到重复的了

代码:

class Solution {
        public int findRepeatNumber(int[] nums) {


            for (int i = 0; i < nums.length; i++) {
                while (i != nums[i]) {
                    if(nums[i]== nums[nums[i]])
                        return nums[i];
                    /*
                     * 交换两数a、b
                     * a=a+b
                     * b=a-b
                     * a=a-b
                     * */
                    if (nums[i] < i) {
                        return nums[i];
                    } else if (nums[i] > i) {
                        int a = nums[i];
                        int b = nums[nums[i]];
                        a += b;
                        b = a - b;
                        a = a - b;
                        nums[nums[i]] = b;
                        nums[i] = a;

                    }

                }
            }


            return -1;

        }

}

image.png

变题:

image.png

改成不能修改数组,之前的两个方法还能用但是书上的解法就用不了了。

这题可以新建数组,然后一个一个填写进去,重复的就return,用O(n)的辅助空间

下面是类似于二分查找的写法

image.png