LeetCode[287] Find the Duplicate Number

LeetCode[287] Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

Binary Search

复杂度
O(NlgN), O(1)

思路
每次通过二分法找到一个值之后,搜索整个数组,观察小于等于这个数的个数。
考虑[1,2,3,2],小于这个位置的数的个数应该是小于等于这个位置的。如果cnt > mid,说明在小于这个位置的数的范围内,存在duplicate,right = mid - 1;

代码

public int findDuplicate(int[] nums) {
    int left = 0, right = nums.length - 1;
    while(left <= right) {
        int mid = left + (right - left) / 2;
        int cnt = 0;
        for(int i = 0; i < nums.length; i ++) {
            if(nums[i] <= mid) cnt ++;
        }
        if(cnt > mid) right = mid - 1;
        else left = mid + 1;
    }
    return left;
}

LinkedList判断循环

复杂度
O(N), O(1)

思路
考虑一定会有duplicate出现,说明,数组里面的值组成了一个环,如果考虑像linkedlist那样。

要做的就是像找linkedlist中的环一样,考虑重复的点在哪里。
考虑用快慢指针。

代码

public int findDuplicate(int[] nums) {
    if(nums.length > 1) {
        int slow = 0;
        int fast = 0;
        while(true) {
           slow = nums[slow];
           fast = nums[nums[fast]];
           if(slow == fast) {
               // case like [1,2,3,1]
               // 把一个指针放回到开头的地方
               slow = 0;
               while(slow != fast) {
                   slow = nums[slow];
                   fast = nums[fast];
               }
               return slow;
           }
        }
    }
    return -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值