Two pointers walk a linked list at different speeds to detect cycles or find midpoints in O(N) time and O(1) memory.
slow fast
| |
A -> B -> C -> D -> E
| (cycle)
v
F -> G -> C
If there is a cycle, fast and slow MUST meet inside it.
slow = fast = headfast and fast.next: slow = slow.next; fast = fast.next.next; if slow is fast -> there is a cycle.Once the two meet, reset one pointer to head and walk both at speed 1. They will meet at the cycle start node.
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast:
return True
return False
def cycle_entry(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast:
slow = head
while slow is not fast:
slow = slow.next
fast = fast.next
return slow
return None
fast.next null-check before dereferencing.head after meeting — you’ll keep looping forever.Two runners on a circular track. The fast runner (2x speed) will lap the slow runner exactly at the cycle’s start if it exists.
Interview tip: If the problem is on a linked list and asks for constant extra space, try fast/slow first.