Detect Cycle in Linked List Floyd's Algorithm in DSA Java - Time & Space Complexity
We want to understand how long it takes to check if a linked list has a cycle using Floyd's Algorithm.
How does the time needed grow as the list gets longer?
Analyze the time complexity of the following code snippet.
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return true;
}
}
return false;
}
This code checks if a linked list has a cycle by moving two pointers at different speeds.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop moves the slow pointer one step and the fast pointer two steps through the list.
- How many times: At most, the loop runs until the fast pointer reaches the end or the two pointers meet inside a cycle.
As the list length n grows, the number of steps the pointers take grows roughly in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The steps increase roughly one-to-one with the list size.
Time Complexity: O(n)
This means the time to detect a cycle grows linearly with the number of nodes in the list.
[X] Wrong: "Because there are two pointers, the time is doubled or squared."
[OK] Correct: Both pointers move through the list together, so the total steps still grow linearly, not squared.
Understanding this linear time check is a key skill for working with linked lists and detecting cycles efficiently.
"What if we used only one pointer moving one step at a time to detect a cycle? How would the time complexity change?"
Practice
Solution
Step 1: Understand Floyd's Algorithm concept
It uses two pointers: a slow pointer moving one step at a time and a fast pointer moving two steps at a time.Step 2: Detect cycle by pointer meeting
If there is a cycle, the fast pointer will eventually meet the slow pointer inside the loop.Final Answer:
Use two pointers moving at different speeds to detect a cycle -> Option AQuick Check:
Two pointers at different speeds detect cycle [OK]
- Thinking counting nodes detects cycle
- Assuming reversing list helps detect cycle
- Using extra memory instead of pointers
Solution
Step 1: Initialize both pointers at head
Both slow and fast pointers start at the head node to begin traversal.Step 2: Move pointers at different speeds
Slow moves one step, fast moves two steps from the same start point.Final Answer:
ListNode slow = head; ListNode fast = head; -> Option CQuick Check:
Both pointers start at head [OK]
- Starting fast pointer ahead causing null errors
- Initializing slow pointer as null
- Starting pointers at different nodes incorrectly
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; this.next = null; }
}
public class Test {
public static boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
public static void main(String[] args) {
ListNode a = new ListNode(1);
ListNode b = new ListNode(2);
ListNode c = new ListNode(3);
a.next = b; b.next = c; c.next = b;
System.out.println(hasCycle(a));
}
}Solution
Step 1: Analyze the linked list structure
Node c points back to node b, creating a cycle in the list.Step 2: Floyd's algorithm detects cycle
Slow and fast pointers will meet inside the cycle, so method returns true.Final Answer:
true -> Option BQuick Check:
Cycle exists, so output is true [OK]
- Assuming no cycle because list looks linear
- Confusing output with false
- Ignoring pointer movement conditions
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}Solution
Step 1: Check pointer initialization
Fast pointer starts at head.next, which can cause missing cycle detection if list has only one node.Step 2: Correct initialization for reliable detection
Both slow and fast pointers should start at head to ensure proper cycle detection.Final Answer:
fast pointer should start at head, not head.next -> Option DQuick Check:
Start both pointers at head [OK]
- Starting fast pointer ahead causing missed cycles
- Changing slow pointer speed incorrectly
- Incorrect loop condition usage
Solution
Step 1: Detect cycle using Floyd's algorithm
When slow and fast pointers meet, a cycle is confirmed.Step 2: Reset slow pointer to head and move both pointers one step
Move slow and fast pointers one step at a time; the node where they meet is the cycle start.Final Answer:
After detecting cycle, reset slow to head and move both pointers one step until they meet -> Option AQuick Check:
Reset slow and move both pointers to find cycle start [OK]
- Trying to find cycle start without resetting slow pointer
- Counting nodes instead of pointer movement
- Using extra memory unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
