Find the Duplicate Number

Problem

The array has n + 1 numbers, and every number is between 1 and n. Exactly one value appears more than once (it can appear many times). Print that value. Do not change the array. The best way uses O(1) extra memory.

Constraints

  • 2 <= n + 1 <= 10^5
  • 1 <= a[i] <= n
  • exactly one repeated value

Examples

Input

5
1 3 4 2 2

Output

2

Solutions

Best approachTime O(n)Space O(1)

Because there are n + 1 numbers in the range 1..n, following 'position to value' must enter a cycle, and the cycle starts at the repeated value. Floyd's two-pointer method finds the start of the cycle with O(1) memory and without changing the array.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Find the duplicate.
 * Input   : n + 1, then the numbers.
 * Output  : The repeated value.
 * Approach: Floyd cycle detection.
 * Time    : O(n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static int solve(int[] a) {
        // Step 1: Treat the array as a linked list: position i points to a[i].
        // A repeated value means two positions point to one place: a cycle.
        int slow = a[0];
        int fast = a[a[0]];
        // Step 2: Floyd's cycle detection. The slow pointer moves one step and the fast pointer two steps until they meet inside the cycle.
        while (slow != fast) {
            slow = a[slow];
            fast = a[a[fast]];
        }
        // Step 3: Restart one pointer from the start. Moving both one step at a time, they meet at the entrance of the cycle: the duplicate.
        slow = 0;
        while (slow != fast) {
            slow = a[slow];
            fast = a[fast];
        }
        return slow;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        System.out.println(solve(a));
    }
}
Hints (2)
  1. Why must a cycle exist?
  2. What is the start of the cycle?