Reverse a Singly Linked List Recursive in DSA C++ - Time & Space Complexity
We want to understand how the time needed to reverse a linked list using recursion changes as the list grows.
How does the number of steps grow when the list gets longer?
Analyze the time complexity of the following code snippet.
Node* reverseList(Node* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
Node* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
This code reverses a singly linked list by calling itself on the next node until it reaches the end, then rewires the pointers backward.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive call on the next node.
- How many times: Once for each node in the list, so n times for n nodes.
Each node causes one recursive call, so the total steps grow directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 recursive calls and rewiring steps |
| 100 | About 100 recursive calls and rewiring steps |
| 1000 | About 1000 recursive calls and rewiring steps |
Pattern observation: The work grows linearly as the list size increases.
Time Complexity: O(n)
This means the time to reverse the list grows in direct proportion to the number of nodes.
[X] Wrong: "Recursion makes this algorithm slower than iterative because it repeats work multiple times."
[OK] Correct: Each node is visited exactly once in the recursion, so no repeated work happens. The recursion just adds function call overhead but does not increase the number of steps beyond n.
Understanding recursive reversal shows you can think about problems in different ways and handle linked lists confidently, a skill often valued in interviews.
"What if we changed the recursion to an iterative loop? How would the time complexity change?"
Practice
Solution
Step 1: Understand recursion on linked list
Recursion works by solving a smaller part first, here reversing from the next node onward.Step 2: Fix current node's pointer after recursion
After reversing the rest, the current node's next node should point back to current node, then current node points to null.Final Answer:
Reverse the rest of the list first, then fix the current node's next pointer -> Option AQuick Check:
Recursive reversal = Reverse rest first [OK]
- Trying to swap data instead of pointers
- Not setting current node's next to null
- Confusing iterative and recursive methods
Solution
Step 1: Identify base cases for recursion
Base case should handle empty list and single node list, both are already reversed.Step 2: Choose condition covering both cases
Condition 'head == nullptr || head->next == nullptr' returns head for empty or single node list.Final Answer:
if (head == nullptr || head->next == nullptr) return head; -> Option BQuick Check:
Base case = empty or single node [OK]
- Returning nullptr for single node list
- Not handling empty list
- Incorrectly modifying head in base case
Node* reverse(Node* head) {
if (!head || !head->next) return head;
Node* newHead = reverse(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}Solution
Step 1: Trace recursion calls
reverse(1) calls reverse(2), which calls reverse(3). reverse(3) returns node 3 as base case.Step 2: Reverse pointers on return
On unwind from reverse(3), in reverse(2): head(2)->next(3)->next = 2 so 3->next=2, then 2->next=nullptr. Then in reverse(1): 2->next=1, 1->next=nullptr.Final Answer:
3 -> 2 -> 1 -> null -> Option DQuick Check:
Reversed list = 3->2->1 [OK]
- Not setting head->next to nullptr causing cycle
- Confusing node values order
- Returning wrong node as new head
Node* reverse(Node* head) {
if (!head || !head->next) return head;
Node* newHead = reverse(head->next);
head->next->next = head;
return newHead;
}Solution
Step 1: Analyze missing pointer update
Function misses setting 'head->next = nullptr', causing cycle in reversed list.Step 2: Fix by setting 'head->next = nullptr'
Adding 'head->next = nullptr;' breaks old link, preventing cycle and correctly terminates list.Final Answer:
Add 'head->next = nullptr;' before returning newHead -> Option CQuick Check:
Break old next link to avoid cycle [OK]
- Forgetting to break old next pointer
- Incorrect base case causing null pointer dereference
- Returning wrong node as new head
Node* reverseCount(Node* head, int &count) {
if (!head || !head->next) {
count++;
return head;
}
Node* newHead = reverseCount(head->next, count);
head->next->next = head;
head->next = nullptr;
count++;
return newHead;
}
What will be the value of count after reversing a list with 4 nodes?Solution
Step 1: Understand counting in base case
When recursion reaches last node, count increments by 1 for that node.Step 2: Count increments on each return step
Each return from recursion increments count by 1 for each node processed, total nodes counted equals list length.Final Answer:
4 -> Option AQuick Check:
Count increments once per node [OK]
- Counting only in base case missing other nodes
- Incrementing count twice per node
- Not passing count by reference
Ready to prove it?
Pass the test and this pattern moves unknown
