Detect Cycle in Linked List Floyd's Algorithm in DSA C - Time & Space Complexity
We want to understand how long it takes to check if a linked list has a cycle using Floyd's Algorithm.
The question is: how does the time needed grow as the list gets longer?
Analyze the time complexity of the following code snippet.
// Detect cycle using Floyd's Algorithm
int hasCycle(Node* head) {
Node *slow = head, *fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return 1; // cycle found
}
}
return 0; // no cycle
}
This code moves two pointers through the list at different speeds to find a cycle.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves the slow pointer one step and the fast pointer two steps each time.
- How many times: At most, the loop runs proportional to the number of nodes in the list before detecting a cycle or reaching the end.
As the list size grows, the number of steps to find a cycle or confirm none 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 directly with the number of nodes, not faster or slower.
Time Complexity: O(n)
This means the time to detect a cycle grows linearly with the list size.
[X] Wrong: "Because the fast pointer moves twice as fast, the algorithm runs in half the time, so it is O(1)."
[OK] Correct: Even though the fast pointer moves faster, the number of steps still depends on the list length, so the time grows linearly, not constant.
Understanding this algorithm's time complexity shows you can analyze pointer-based algorithms and reason about loops, a key skill in coding interviews.
"What if we changed the fast pointer to move three steps at a time? How would the time complexity change?"
Practice
Solution
Step 1: Understand Floyd's Algorithm goal
Floyd's Cycle Detection Algorithm is designed to find if a linked list has a cycle or loop.Step 2: Compare with other linked list operations
Sorting, reversing, or finding the middle element are different operations and not related to cycle detection.Final Answer:
To detect if there is a cycle (loop) in the linked list -> Option BQuick Check:
Cycle detection = Detect cycle [OK]
- Confusing cycle detection with sorting
- Thinking it finds middle element
- Assuming it reverses the list
Solution
Step 1: Understand pointer initialization in Floyd's algorithm
Both slow and fast pointers start at the head node to begin traversal.Step 2: Check options for correct initialization
Node *slow = head; Node *fast = head; initializes both pointers at head, which is the standard approach.Final Answer:
Node *slow = head; Node *fast = head; -> Option DQuick Check:
Both pointers start at head [OK]
- Starting fast pointer ahead of slow incorrectly
- Initializing slow as NULL
- Skipping initialization of one pointer
typedef struct Node {
int data;
struct Node *next;
} Node;
int detectCycle(Node *head) {
Node *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return 1;
}
return 0;
}
// Assume linked list has a cycle
printf("%d", detectCycle(head));Solution
Step 1: Analyze the detectCycle function logic
The function moves slow pointer by one and fast pointer by two nodes. If they meet, it returns 1 indicating a cycle.Step 2: Given the list has a cycle, pointers will meet
Since the list has a cycle, slow and fast pointers will eventually meet, so function returns 1.Final Answer:
1 -> Option AQuick Check:
Cycle present = return 1 [OK]
- Assuming function returns 0 for cycle
- Thinking code causes infinite loop
- Confusing return values
int detectCycle(Node *head) {
Node *slow = head, *fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next;
if (slow == fast) return 1;
fast = fast->next;
}
return 0;
}Solution
Step 1: Analyze pointer movements in the loop
Slow moves one step, fast moves one step, then checks if slow == fast, before the second fast move.Step 2: Problem with check timing
In Floyd's algorithm, fast should move two steps before the cycle check. Here, the check occurs after fast has moved only one step, and the second fast move is done without checking if fast->next is NULL, which can cause a NULL pointer dereference.Final Answer:
fast pointer moves two steps but not checked for NULL before second move -> Option AQuick Check:
Second fast move lacks NULL check [OK]
- Checking cycle after fast's first step only
- Confusing slow and fast pointer steps
- Not initializing pointers correctly
Solution
Step 1: Detect cycle and pointers meet inside the loop
Floyd's algorithm detects cycle when slow and fast pointers meet inside the loop.Step 2: Reset slow to head and move both pointers one step at a time
Reset slow to head, then move slow and fast one step each until they meet again; this meeting point is the cycle start.Final Answer:
Reset slow pointer to head, then move slow and fast one step at a time until they meet -> Option CQuick Check:
Reset slow + move both one step = cycle start [OK]
- Moving fast pointer two steps again
- Trying to count nodes to find cycle start
- Reversing list to detect cycle start
Ready to prove it?
Pass the test and this pattern moves unknown
