medium

Find the Duplicate Number

Find the one repeated number without modifying the array.

1. Define the problem

Find the Duplicate Number

Given an array of n + 1 integers where every value is between 1 and n, there is exactly one repeated value (it may repeat more than once). Find that duplicate number without modifying the array and using only constant extra space. Treat each value as a pointer to another index — this turns the array into a linked list where the duplicate value creates a cycle, and Floyd's cycle detection (the classic slow/fast pointer trick) finds exactly where that cycle begins.

Constraints

  • 1 ≤ n ≤ 105
  • nums.length == n + 1
  • 1 ≤ numsi ≤ n
  • There is exactly one repeated number in nums, but it may repeat more than once.

Example

Inputnums = [1, 3, 4, 2, 2]
Output2

Explanation Following the chain of indices 0 → 1 → 3 → 2 → 4 → 2 loops back onto index 2, revealing that 2 is the duplicate.

2. Know the words first

In plain terms

Pointer to another index
Instead of reading numsi as just a number, treat it as "go to index numsi next" — the same idea used to walk a linked list.
3. Visualize the solution

Slow and fast pointers meet inside the cycle, then find its start

Slow and fast pointers meet inside the cycle, then find its start
Statusinit

Start both slow and fast at nums[0] = 1.

What happens in this step

slow = nums[0] = 1
fast = nums[0] = 1
Step 1 of 6

Steps to visualize

  1. Start both slow and fast at nums0, then move slow one step (to numsslow) and fast two steps (to nums[numsfast]) per round.
  2. Because a value repeats, this chain must eventually loop, so slow and fast are guaranteed to meet somewhere inside that loop.
  3. Once they meet, reset slow back to nums0 but leave fast where it is.
  4. The highlight box always stretches between the two pointer positions, whichever one is further left.
  5. Now move both one step at a time — the index where they meet again is exactly the duplicate value.
4. Walk through the code

Walk through the code

Same walkthrough, now with the code. Press Next to move one step and watch which lines run.

Slow and fast pointers meet inside the cycle, then find its start
Statusinit

Start both slow and fast at nums[0] = 1.

What happens in this step

slow = nums[0] = 1
fast = nums[0] = 1
Step 1 of 6
5. Solution

Solution

solution.tsTypeScript
function findDuplicate(nums) {
  let slow = nums[0];
  let fast = nums[0];

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

  slow = nums[0];

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

  return slow;
}
Time
O(n)
Space
O(1)
6. Test cases

Test cases

InputExpectedCovers
nums = [1, 3, 4, 2, 2]2example from the docstring
nums = [1, 1]1smallest valid input: n = 1 with the only possible value repeated
nums = [3, 1, 3, 4, 2]3the duplicate value sits at the very first index
nums = [2, 2, 2, 2, 2]2the same value repeated across every position
nums = [1, 2, 3, 4, 4]4the duplicate is the largest allowed value
nums = [2, 4, 1, 4, 3]4the duplicate is reached partway through a longer chain