We treat the array as a linked list where nums[i] points to the index nums[i]. Since there's a duplicate, there must be a cycle in this linked list. We can use Floyd's Cycle-Finding Algorithm (Tortoise and Hare).
- Initialize two pointers,
slowandfast, both atnums[0]. - Move
slowone step (slow = nums[slow]) andfasttwo steps (fast = nums[nums[fast]]) until they meet. - Once they meet, move
slowback tonums[0]. - Move both
slowandfastone step at a time. The point where they meet again is the start of the cycle, which corresponds to the duplicate number.
- Time Complexity: O(N), as we traverse the "list" a small number of times.
- Space Complexity: O(1), no extra space besides pointers.
def find_duplicate(nums):
# Phase 1: Finding the intersection point in the cycle
slow = nums[0]
fast = nums[0]
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast:
break
# Phase 2: Finding the entrance to the cycle
slow = nums[0]
while slow != fast:
slow = nums[slow]
fast = nums[fast]
return slow