LeetCode – Find the Duplicate Number (Java)

Given an array 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:
1) You must not modify the array (assume the array is read only).
2) You must use only constant, O(1) extra space.
3) Your runtime complexity should be less than O(n^2).
4) There is only one duplicate number in the array, but it could be repeated more than once.

Java Solution - Finding Cycle

The following shows how fast and slow pointers solution works. It basically contains 2 steps: 1) find the meeting point 2) start from the beginning and the meeting point respectively and find the intersection point.

public int findDuplicate(int[] nums) {
    int slow = 0;
    int fast = 0;
 
    do{
        slow = nums[slow];
        fast = nums[nums[fast]];
    } while(slow != fast);
 
    int find = 0;
 
    while(find != slow){
        slow = nums[slow];
        find = nums[find];
    }
    return find;
}

If we can assume there is only one duplicate number, it can be easily solved by using the sum of the array.

public int findDuplicate(int[] nums) {
    int sum = 0;
    for(int i: nums){
        sum+=i;
    }
 
    int n=nums.length;
    return sum - ((n-1)*n)/2;
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • p.andrey

    Thanks.
    However, I’m familiar with the problem… actually is one of my favorite proofs… my comment was related only to the picture. In my imho is highly unlikely to understand the correctness from it, and that’s why I’ve added the link (see above) where it is nicely explained.

  • alexwest11

    see my explanation later!

  • alexwest11

    this algorithm based (loosely ) on famous / finding loop in linked list /
    where some element point on other element before

    solution was

    #1 use 1step, 2step pointers, obviously they will meet. inside loop

    #2 run cycle again,to find length of loop, lets say K elements, keep pointer

    #3 pointer from start of list run K steps

    #4 run both pointers , 1step each, as soon as they meet , its start of loop!!!

    i am not sure about this simple solution finding /find/ .2d while.

    need think more!!!!!!!

  • p.andrey

    I wonder if someone actually understood the algorithm by eyeballing that picture (the one with slow and fast pointers)? I didn’t… however, here is the best explanation I could find: http://keithschwarz.com/interesting/code/?dir=find-duplicate

  • tranovis
  • Marina

    well it shouldn’t : “Assume that there is only one duplicate number, find the duplicate one.”

  • d_r_o_i_d

    Check the requirements again:
    There is only one duplicate number in the array, but it could be repeated more than once.

  • Yi-jhe Huang

    Assume that there is only one duplicate number, find the duplicate one.

  • kun zhang

    can’t pass test on input [1,1,1,2].

  • Yi-jhe Huang

    Using the math solution:
    totalSum – n*(n+1)/2
    = 4 – (2*3/2)
    = 4 – 3
    = 1

  • Ankit Shah

    okay this makes sense with the example your solution might work

  • Yi-jhe Huang

    Let n be the maximum element in the input nums array.
    Can you take one case as an example?

  • Ankit Shah

    Hi yi-jhe Huang, that will only work if the n starts at 0. here the question is n starts from 1.

  • Yi-jhe Huang

    How about using the math solution:
    totalSum – n*(n+1)/2