Linked List Cycle
Easy · Linked List · Explanation and code example
Fast And Slow Pointers
How it works
We use two pointers moving through the list at different speeds:
slowmoves one step at a timefastmoves two steps at a time
If the list has a cycle, the fast pointer will eventually "lap" the slow pointer, meaning they will meet at some node inside the cycle.
If the list has no cycle, the fast pointer will reach the end (null) and the loop stops.
This method is efficient and uses constant extra space.
Steps
- Initialize two pointers:
slow = headfast = head
- Move through the list:
slowmoves one step.fastmoves two steps.
- If at any point
slow == fast, a cycle exists, returntrue. - If
fastreaches the end (nullorfast.nextisnull), no cycle exists, returnfalse.
Complexity
- Time complexity:
O(n) - Space complexity:
O(1)
Things to watch for
Not Checking if Fast Pointer Can Advance Safely
Before moving the fast pointer two steps, you must verify both fast and fast.next are not null. Checking only fast != null before accessing fast.next.next causes a null pointer exception when the list has an odd number of nodes without a cycle.
Comparing Node Values Instead of Node References
The cycle detection requires comparing whether two pointers reference the same node object, not whether they have the same value. Using value equality (slow.val == fast.val) incorrectly detects cycles when two different nodes happen to have the same value.
Python code example
from typing import Optional
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
C++ code example
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) {
return true;
}
}
return false;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.