As asked
Given the head of a linked list, determine whether the list contains a cycle. If it does, return the node where the cycle begins. You must solve this without allocating additional data structures proportional to the size of the list.
Sample answer outline
Floyd's tortoise-and-hare algorithm: two pointers, one moving one step and one moving two steps at a time. If they meet, a cycle exists. To find the start, reset one pointer to head and advance both one step at a time until they meet again; that node is the cycle entry. Time O(n), space O(1). A complete answer explains WHY the meeting point math works (the distance from head to cycle start equals the distance from meeting point to cycle start, modulo cycle length).
Reference implementation (python)
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def detectCycle(head: ListNode) -> ListNode:
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 NoneExpect these follow-ups
- What if the list is doubly linked? Does your algorithm change?
- How would you solve this if the list were stored on disk and too large to fit in memory?