Find Middle Element of Linked List in DSA C - Time & Space Complexity
We want to know how the time to find the middle element in a linked list changes as the list grows.
How many steps does it take to reach the middle as the list gets longer?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
struct Node* next;
};
int findMiddle(struct Node* head) {
struct Node* slow = head;
struct Node* fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow->data;
}
This code uses two pointers moving at different speeds to find the middle node of a linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves the fast pointer two steps and the slow pointer one step each time.
- How many times: About half the number of nodes in the list, since fast moves twice as fast.
As the list size grows, the number of loop steps grows roughly half as fast.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5 |
| 100 | 50 |
| 1000 | 500 |
Pattern observation: The steps increase linearly with input size, just about half as many steps as nodes.
Time Complexity: O(n)
This means the time to find the middle grows directly with the number of nodes in the list.
[X] Wrong: "Since the fast pointer jumps two steps, the time complexity is O(n/2), which is faster than O(n)."
[OK] Correct: We ignore constants in Big-O, so O(n/2) is the same as O(n). The time still grows linearly with input size.
Understanding this method shows you can use clever pointer techniques to solve problems efficiently, a skill valued in many coding challenges.
"What if we used only one pointer to traverse the list once and counted nodes first, then traversed again to the middle? How would the time complexity change?"
Practice
Solution
Step 1: Understand two-pointer technique
One pointer moves one node at a time (slow), the other moves two nodes at a time (fast).Step 2: Identify middle when fast reaches end
When fast pointer reaches the end, slow pointer will be at the middle node.Final Answer:
Use one slow pointer moving one step and one fast pointer moving two steps until fast reaches the end -> Option DQuick Check:
Two-pointer technique = slow one step, fast two steps [OK]
- Moving both pointers at the same speed
- Counting nodes first instead of using pointers
- Reversing the list unnecessarily
head?Solution
Step 1: Initialize both pointers at head
Both slow and fast pointers start at the head node to traverse the list properly.Step 2: Check pointer initialization correctness
Only Node *slow = head; Node *fast = head; initializes both pointers correctly at head; others start one pointer at NULL or next node incorrectly.Final Answer:
Node *slow = head; Node *fast = head; -> Option BQuick Check:
Both pointers start at head [OK]
- Starting one pointer at NULL
- Starting pointers at next node instead of head
- Not initializing pointers before loop
typedef struct Node {
int data;
struct Node *next;
} Node;
int main() {
Node n3 = {30, NULL};
Node n2 = {20, &n3};
Node n1 = {10, &n2};
Node *head = &n1;
Node *slow = head, *fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
printf("%d", slow->data);
return 0;
}Solution
Step 1: Trace pointer movements
Initially, slow and fast point to 10. After first loop, slow moves to 20, fast moves to 30. Next loop fast->next is NULL, loop ends.Step 2: Identify slow pointer position
Slow pointer is at node with data 20, which is the middle element.Final Answer:
20 -> Option CQuick Check:
Middle element = 20 [OK]
- Assuming middle is first node
- Confusing fast pointer position with slow
- Ignoring loop exit condition
Node *slow = head;
Node *fast = head;
while (fast != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow->data;Solution
Step 1: Analyze loop condition
The loop checks only fast != NULL, but fast->next could be NULL causing fast->next->next to crash.Step 2: Correct loop condition
Adding fast->next != NULL prevents dereferencing NULL pointer, avoiding runtime error.Final Answer:
Change loop condition to while (fast != NULL && fast->next != NULL) -> Option AQuick Check:
Check both fast and fast->next not NULL [OK]
- Not checking fast->next before accessing
- Moving slow pointer incorrectly
- Assuming code runs without null checks
Solution
Step 1: Trace pointers on even-length list
Start slow and fast at 5. After first iteration, slow=10, fast=15. Next iteration, slow=15, fast=NULL (end).Step 2: Identify middle node returned
When fast reaches NULL, slow points to 15, which is the second middle node in even-length list.Final Answer:
15 (the second middle node) -> Option AQuick Check:
Two-pointer method returns second middle in even list [OK]
- Assuming first middle is returned
- Confusing head or last node as middle
- Not tracing pointer steps carefully
Ready to prove it?
Pass the test and this pattern moves unknown
