法一,使用Set

一次遍历,遍历的时候添加元素,如果add返回为false,则此元素重复;

    public int duplicate (int[] numbers) {
        // write code here
        Set<Integer> set = new HashSet<>();
        for(int i=0;i<numbers.length;i++){
            if(!set.add(numbers[i])){
                return numbers[i];
            }
        }
        return -1;
    }

时间复杂度:O(N) 空间复杂度:O(N)

法二,数组重排

根据其中内容只有[0,nums.length-1]的特点。将nums[i]都排列到i的位置上去

一次遍历,如果nums[i] == i,则继续循环;如果nums[i] == nums[nums[i]],则返回nums[i],为重复元素;反之,则交换到对应位置。

     public int duplicate(int[] nums) {
        // write code here
        int i = 0, n = nums.length;
        while (i < n) {
            if (nums[i] == i) {
                i++;
            } else {
                if (nums[i] == nums[nums[i]]) {
                    return nums[i];    //找到重复元素
                } else {
                    //这里需特别注意顺序,必须nums[nums[i]]在前,否则死循环
                    int t = nums[nums[i]];
                    nums[nums[i]] = nums[i];
                    nums[i] = t;
                }
            }
        }
        return -1;
    }