Problem Statement in English
You’re given a linked list node head. Your task is to return the node at which the cycle begins, if there is a cycle in the linked list, and None otherwise.
Approach
I feel that to be able to solve this problem you need to know a little trick beforehand. We’ll get to that.
But first, this problem builds on a previous problem, where we used the Fast and Slow Pointer Technique to find the middle of a linked list.
But how do we find the node at which the cycle begins?
That’s the part that you just need to know beforehand. I don’t think it’s really intuitive, and so the chances of you just figuring it out during your interview are kind of slim.
Here’s how it works. Once you’ve got a hold of a node that’s inside the cycle, you can find the node at which the cycle begins by starting another pointer from the head of the linked list, and moving both pointers one step at a time. The point at which they meet is the node at which the cycle begins.
See? I told you it wasn’t intuitive.
Solution in Python
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head is None or head.next == None:
return None
fast, slow = head, head
while fast and fast.next:
fast = fast.next.next
assert slow != None
slow = slow.next
if fast == slow:
break
if fast == slow:
slow2 = head
while slow2 != slow:
assert slow != None
assert slow2 != None
slow2 = slow2.next
slow = slow.next
return slow
else:
return None
Complexity
Time: $O()$
Space: $O()$
Mistakes I Made
And we are done.