287. 寻找重复数
  1. 寻找重复数

难度中等790

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和
n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

示例 1:

输入: [1,3,4,2,2]
输出: 2

示例 2:

输入: [3,1,3,4,2]
输出: 3

快慢指针

// 快慢指针 如果数组中有重复的数字,那么必定会形成环
// 时间复杂度为O(N)
public int findDuplicate(int[] nums) {
    int slow = 0;
    int fast = 0;

    slow = nums[slow];
    fast = nums[nums[fast]];

    while(fast!=slow){
        slow = nums[slow];
        fast = nums[nums[fast]];
    }

    int pre1 = 0;
    int pre2 = slow;
    while(pre1!=pre2){
        pre1 = nums[pre1];
        pre2 = nums[pre2];
    }
    return pre1;
}

二分

// 二分查找
// 时间复杂度O(NlogN) 二分logN 遍历数组O(n)
public int findDuplicate(int[] nums) {
    int len = nums.length;
    int l = 1;
    int r = len-1;
    //查找小于mid的值
    while(l<r){
        int mid = (l+r) >>> 1;
        int cnt = 0;
        for(int i=0;i<len;i++){
            if(nums[i] <= mid){
                cnt++;
            }
        }
        //大于mid 则在左边
        if(cnt > mid){
            r = mid;
        }else {
            // 小于mid 则在右边
            l = mid+1;
        }
    }
    return l;
}