Reverse a Doubly Linked List in DSA Typescript - Time & Space Complexity
We want to know how the time to reverse a doubly linked list grows as the list gets bigger.
Specifically, how many steps does it take to flip the list order?
Analyze the time complexity of the following code snippet.
function reverseDoublyLinkedList(head: Node | null): Node | null {
let current = head;
let temp = null;
while (current !== null) {
temp = current.prev;
current.prev = current.next;
current.next = temp;
current = current.prev;
}
if (temp !== null) {
head = temp.prev;
}
return head;
}
This code flips the direction of the doubly linked list by swapping the previous and next links for each node.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that visits each node once.
- How many times: Exactly once per node, so as many times as the list length.
Each node is visited once to swap its pointers.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 swaps |
| 100 | About 100 swaps |
| 1000 | About 1000 swaps |
Pattern observation: The number of steps grows directly with the list size.
Time Complexity: O(n)
This means the time to reverse the list grows linearly with the number of nodes.
[X] Wrong: "Reversing a doubly linked list takes more than linear time because of pointer swaps."
[OK] Correct: Each node is visited once, and swapping pointers is a constant-time step, so total time grows linearly.
Understanding this linear time reversal helps you show clear thinking about linked list operations, a common topic in interviews.
"What if we tried to reverse the list using recursion instead of a loop? How would the time complexity change?"
Practice
Solution
Step 1: Understand the structure of a doubly linked list
A doubly linked list has nodes with pointers to both previous and next nodes.Step 2: Purpose of reversing
Reversing swaps the direction so the last node becomes the first and the first becomes the last.Final Answer:
To reverse the order of nodes so the last becomes first and vice versa -> Option BQuick Check:
Reversing = changing node order [OK]
- Confusing reversing with deleting nodes
- Thinking reversing sorts the list
- Assuming it converts to singly linked list
next and prev pointers of a node in a doubly linked list?Solution
Step 1: Identify correct swapping logic
Swapping pointers requires a temporary variable to hold one pointer before assignment.Step 2: Check each option
let temp = node.next; node.next = node.prev; node.prev = temp; correctly uses a temp variable to swapnextandprev. Others either assign incorrectly or lose references.Final Answer:
let temp = node.next; node.next = node.prev; node.prev = temp; -> Option AQuick Check:
Swap pointers using temp variable [OK]
- Assigning pointers without temp causes data loss
- Mixing up
nextandprevassignments - Using incorrect pointer references
class Node {
data: number;
next: Node | null = null;
prev: Node | null = null;
constructor(data: number) { this.data = data; }
}
function reverse(head: Node | null): Node | null {
let current = head;
let temp: Node | null = null;
while (current !== null) {
temp = current.prev;
current.prev = current.next;
current.next = temp;
current = current.prev;
}
if (temp !== null) {
head = temp.prev;
}
return head;
}
// Create list: 1 <-> 2 <-> 3
const n1 = new Node(1);
const n2 = new Node(2);
n1.next = n2; n2.prev = n1;
const n3 = new Node(3);
n2.next = n3; n3.prev = n2;
const newHead = reverse(n1);
// Print reversed list
let result = [];
let node = newHead;
while (node !== null) {
result.push(node.data);
node = node.next;
}
console.log(result);Solution
Step 1: Trace pointer swaps in the loop
Each node swaps itsnextandprev. The loop moves forward using the oldnextpointer now inprev.Step 2: Update head to new first node
After loop,headis updated to last node processed, which is node with data 3.Final Answer:
[3, 2, 1] -> Option CQuick Check:
Reversed list order = [3, 2, 1] [OK]
- Not updating head after reversal
- Confusing
nextandprevin loop - Printing original list order
function reverse(head: Node | null): Node | null {
let current = head;
while (current !== null) {
let temp = current.next;
current.next = current.prev;
current.prev = temp;
current = current.next;
}
return head;
}Solution
Step 1: Check pointer swapping logic
The swapping ofnextandprevis correct using a temp variable.Step 2: Verify head update after reversal
The function returns originalheadwithout updating it to the new first node, so the reversed list head is incorrect.Final Answer:
The function does not update the head to the new first node after reversal -> Option DQuick Check:
Head must update to new first node [OK]
- Forgetting to update head after reversal
- Returning old head instead of new head
- Incorrect loop condition causing infinite loop
Solution
Step 1: Add a counter variable inside the reversal function
Initialize a count variable to zero and increment it each time a node is processed in the reversal loop.Step 2: Return both new head and count
After reversal, return an object containing the updated head and the count of nodes reversed.Final Answer:
Modify the function to use an object return type like { head: Node | null, count: number }, increment count inside the loop, and update head after reversal. -> Option AQuick Check:
Return head and count together after reversal [OK]
- Using global variables instead of local counters
- Not updating head before returning
- Returning count without reversing
Ready to prove it?
Pass the test and this pattern moves unknown
