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(n^2)$$.
    • There is only one duplicate number in the array, but it could be repeated more than once.

Solution

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size()-1;
        if ( n <= 0 ) return 0;
        int l = 1, r = n;
        int mid = 0, lt = 0, gt = 0;
        while ( l <= r-1 ) {
            mid = 0; lt = 0; gt = 0;
            for ( int i = 0; i <= n; i++ ) {
                if ( (l+r)%2 == 0 ) {
                    if ( nums[i] == (l+r)/2 ) mid += 1;
                    if ( mid == 2 ) return (l+r)/2;
                }
                if ( nums[i] >= l and nums[i] <= (l+r-1)/2 ) lt += 1;
                if ( nums[i] <= r and nums[i] >= (l+r+2)/2 ) gt += 1;
            }
            if ( lt > gt ) r = (l+r-1)/2;
            if ( lt < gt ) l = (l+r+2)/2;
        }
        return r;
    }
};

Notes
抽屉原理!
For the first scan, there are $$(n+1)$$ numbers lying in the inclusive interval $$[1, n]$$.

  • If $$(1+n)$$ is odd, the larger half have at least $$\frac{n}{2} + 1$$ numbers. (The new interval is either $$[1, \frac{n}{2}]$$ or $$[\frac{2+n}{2}, n]$$, interval length is $$\frac{n}{2}$$.)
  • If $$(1+n)$$ is even, one has to take special care of the "middle number". The larger have at least $$\frac{n+1}{2}$$ numbers. (The new interval is either $$[1, \frac{n-1}{2}]$$ or $$[\frac{n+3}{2}, n]$$, interval length is $$\frac{n-1}{2}$$.)

Note in the new situations, the following relation still holds: In the "larger half" interval $$[l, r]$$, there are always at least $$(r-l+2)$$ numbers. Thus there must be a duplicate number lying in that interval.

results matching ""

    No results matching ""