Floyd's Cycle Detection: Visualizing LeetCode 287
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
Why Phase 2 Works
- — tail length (start to cycle entrance)
- — distance into the cycle where the pointers meet
- — cycle length
When the pointers collide, slow has taken steps. Fast moves at double speed, so it has taken . The extra steps are full laps around the cycle, so is a multiple of :
Rearranging to solve for :
The part is just full laps around the cycle — they bring you right back to where you started. So walking steps from the meeting point is the same as walking steps, which backs up to the cycle entrance. That’s the same place you reach by walking 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