Linked List Cycle easy
Problem Statement
Given head
, the head of a linked list, determine if the linked list has a cycle in it. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next
pointer. Internally, pos
is used to denote the index of the node that tail's next
pointer is connected to. Note that pos
is not passed as a parameter.
Return true
if there is a cycle in the linked list. Otherwise, return false
.
Example 1
Input: head = [3,2,0,-4], pos = 1 Output: true Explanation: There is a cycle in the linked list, where the tail connects to the second node.
Example 2
Input: head = [1,2], pos = 0 Output: true Explanation: There is a cycle in the linked list, where the tail connects to the first node.
Example 3
Input: head = [1], pos = -1 Output: false Explanation: There is no cycle in the linked list.
Steps
-
Fast and Slow Pointers: Use two pointers,
slow
andfast
.slow
moves one step at a time, andfast
moves two steps at a time. -
Cycle Detection: If there is a cycle, the
fast
pointer will eventually lap theslow
pointer. This is because thefast
pointer is covering ground twice as fast. -
No Cycle: If there's no cycle, the
fast
pointer will reach the end of the list (null
). -
Return Value: Return
true
if the pointers meet (cycle detected), andfalse
otherwise.
Explanation
The algorithm leverages the concept of a "tortoise and hare" race. The fast pointer (hare) moves faster than the slow pointer (tortoise). If there's a cycle, the faster pointer will inevitably catch up to the slower pointer. If there's no cycle, the fast pointer will reach the end of the list before catching the slow pointer. The key insight is that the relative speed difference guarantees a meeting point within the cycle if one exists.
Code
using System;
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
next = null;
}
}
public class Solution {
public bool HasCycle(ListNode head) {
if (head == null || head.next == null) {
return false; // Empty list or single node - no cycle
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false; // Reached the end - no cycle
}
slow = slow.next;
fast = fast.next.next;
}
return true; // Cycle detected
}
}
Complexity
- Time Complexity: O(N), where N is the number of nodes in the linked list. In the worst case (no cycle), the
fast
pointer traverses the entire list. - Space Complexity: O(1). The algorithm uses only a constant amount of extra space for the
slow
andfast
pointers.