~$ alister.pineda

Floyd's Cycle Detection: Visualizing LeetCode 287

Feb 13, 2026 · 2 min read

The Problem

LeetCode 287: given n + 1 integers in the range [1, n], find the duplicate — without modifying the array, in O(1) space.

The trick is to treat the array as a linked list where index i points to nums[i]. Two indices mapping to the same value means a cycle, and the cycle entrance is the duplicate. Floyd’s algorithm finds it in two phases: a fast/slow pointer collision, then a walk from both the start and the meeting point until they converge.

Visualizer

Load an array to see the graph

Why Phase 2 Works

  • LL — tail length (start to cycle entrance)
  • DD — distance into the cycle where the pointers meet
  • CC — cycle length

When the pointers collide, slow has taken L+DL + D steps. Fast moves at double speed, so it has taken 2(L+D)2(L + D). The extra L+DL + D steps are full laps around the cycle, so L+DL + D is a multiple of CC:

L+D=kCL + D = kC

Rearranging to solve for LL:

L=kCDL = kC - D

The kCkC part is just full laps around the cycle — they bring you right back to where you started. So walking L=kCDL = kC - D steps from the meeting point is the same as walking D-D steps, which backs up DD to the cycle entrance. That’s the same place you reach by walking LL steps from the start. So phase 2 just starts one pointer at the head and one at the meeting point — they converge at the entrance.

The Code

def findDuplicate(nums: list[int]) -> int:
    slow = fast = 0
    while True:
        slow = nums[slow]
        fast = nums[nums[fast]]
        if slow == fast:
            break

    slow = 0
    while slow != fast:
        slow = nums[slow]
        fast = nums[fast]

    return slow  # O(n) time, O(1) space