Delete from End of Doubly Linked List in DSA Java - Time & Space Complexity
We want to understand how long it takes to remove the last item from a doubly linked list.
How does the time needed change as the list gets bigger?
Analyze the time complexity of the following code snippet.
public void deleteFromEnd() {
if (tail == null) return; // empty list
if (tail.prev == null) { // only one node
head = null;
tail = null;
return;
}
tail = tail.prev;
tail.next = null;
}
This code removes the last node from a doubly linked list by updating pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Direct pointer updates without loops or recursion.
- How many times: Exactly once per call, no repetition over list size.
Removing the last node always takes the same steps, no matter how big the list is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 4 |
| 100 | 4 |
| 1000 | 4 |
Pattern observation: The number of steps stays the same as the list grows.
Time Complexity: O(1)
This means deleting from the end takes a fixed amount of time regardless of list size.
[X] Wrong: "Deleting from the end takes longer as the list grows because you must find the last node."
[OK] Correct: The doubly linked list keeps a direct reference to the last node (tail), so no searching is needed.
Knowing that deleting from the end is quick helps you explain efficient list operations clearly and confidently.
"What if we did not keep a tail pointer? How would the time complexity change?"
Practice
Solution
Step 1: Identify the last node and its previous node
In a doubly linked list, the last node's previous node is the second last node.Step 2: Update the second last node's next pointer
Set the second last node's next pointer to null, making it the new tail.Final Answer:
The second last node becomes the new tail and its next pointer is set to null. -> Option AQuick Check:
Deleting last node updates tail's next to null [OK]
- Setting head to null instead of updating tail
- Not updating the previous node's next pointer
- Deleting the first node by mistake
dll?Solution
Step 1: Move tail pointer to previous node
Setdll.tailtodll.tail.prevto remove last node reference.Step 2: Set new tail's next pointer to null
Updatedll.tail.nextto null to mark end of list.Final Answer:
dll.tail = dll.tail.prev; dll.tail.next = null; -> Option CQuick Check:
Correct tail update and next pointer null [OK]
- Updating head instead of tail
- Setting tail to null without updating pointers
- Confusing next and prev pointers
class Node {
int data;
Node prev, next;
Node(int d) { data = d; prev = next = null; }
}
class DoublyLinkedList {
Node head, tail;
void deleteFromEnd() {
if (tail == null) return;
if (head == tail) {
head = tail = null;
return;
}
tail = tail.prev;
tail.next = null;
}
}
DoublyLinkedList dll = new DoublyLinkedList();
dll.head = new Node(1);
Node second = new Node(2);
dll.head.next = second;
second.prev = dll.head;
dll.tail = second;
dll.deleteFromEnd();
System.out.println(dll.head.data + " -> " + (dll.head.next == null ? "null" : dll.head.next.data));What is the output?
Solution
Step 1: Setup list with two nodes 1 and 2
Head points to node 1, tail points to node 2, linked properly.Step 2: Delete last node (node 2)
Tail moves to node 1, tail.next set to null, removing node 2.Final Answer:
1 -> null -> Option DQuick Check:
After deletion, only node 1 remains with next null [OK]
- Printing old tail node data
- Not updating tail.next to null
- Confusing head and tail pointers
void deleteFromEnd() {
if (tail == null) return;
tail = tail.prev;
tail.next = null;
}What is the error and how to fix it?
Solution
Step 1: Identify cause of NullPointerException
If list has one node, tail.prev is null, so tail becomes null, then tail.next causes error.Step 2: Fix by checking single node case
Add condition: if head == tail, set head and tail to null before updating pointers.Final Answer:
NullPointerException when list has one node; fix by checking if tail.prev is null. -> Option BQuick Check:
Check single node case before pointer update [OK]
- Not handling single node list
- Assuming tail.prev always exists
- Ignoring null pointer exceptions
Solution
Step 1: Delete last node once
Deleting last node 40 removes it; list becomes 10 <-> 20 <-> 30.Step 2: Delete last node second time
Deleting last node 30 removes it; list becomes 10 <-> 20.Final Answer:
10 <-> 20 -> Option AQuick Check:
Two deletions remove last two nodes [OK]
- Deleting from head instead of tail
- Not updating tail pointer after deletion
- Confusing node values after deletion
Ready to prove it?
Pass the test and this pattern moves unknown
