Given the head of a singly linked list, determine whether the list contains a cycle. A cycle exists if, while traversing the list through next pointers, you encounter a node that has already been visited instead of eventually reaching nullptr.
[Naive Approach] Using HashSet - O(n) Time and O(n) Space
The idea is to insert the nodes in the Hashset while traversing and whenever a node is encountered that is already present in the hashset (which indicates there's a cycle (loop) in the list) then return true. If the node is NULL, represents the end of Linked List, return false as there is no loop.
Output
true
[Expected Approach] Using Floyd's Cycle-Finding Algorithm - O(n) Time and O(1) Space
This idea is to use Floyd's Cycle-Finding Algorithm to find a loop in a linked list. It uses two pointers slow and fast, fast pointer move two steps ahead and slow will move one step ahead at a time.
Algorithm:
Traverse linked list using two pointers.
Move one pointer(slow) by one step ahead and another pointer(fast) by two steps ahead.
If these pointers meet at the same node then there is a loop. If pointers do not meet then the linked list doesn't have a loop.
Below is the illustration of above algorithm:
Why meeting is guaranteed if a cycle exists?
Let: m = number of nodes before the cycle starts and c = length of the cycle (number of nodes in the loop)
When both pointers enter the cycle: At that point, the difference in steps between fast and slow increases by 1 each turn (because fast moves 1 step more than slow each iteration). This difference is taken modulo c because positions wrap around inside the cycle.
Mathematically:
If d is the difference in positions (mod c), then each iteration: d ≡ d + 1 (mod c)
Since 1 and c are coprime, adding 1 repeatedly cycles through all residues 0, 1, 2, …, c-1.
Thus, eventually d ≡ 0 → meaning both pointers are at the same node (meeting point).