Remove Nth Node From End of List
Master this topic with zero to advance depth.
Remove Nth Node From End of List
Given the head of a linked list, remove the n^{th} node from the end of the list and return its head.
Visual Representation
List: 1 -> 2 -> 3 -> 4 -> 5, n = 2
Step 1: Move Fast pointer n=2 steps ahead.
Dummy -> 1 -> 2 -> 3 -> 4 -> 5
S F
Step 2: Move both S and F until F reaches the end.
Dummy -> 1 -> 2 -> 3 -> 4 -> 5 -> null
S F
Step 3: S.next = S.next.next (Removes 4)
1 -> 2 -> 3 -> 5Examples
The second node from the end is 4. Removing it results in [1,2,3,5].
Level I: Two Pass (Length Calculation)
Intuition
To remove the n^{th} node from the end, we calculate the total length L of the list. The node to remove is at index (L - n) from the start (0-indexed if using a dummy node).
Detailed Dry Run
Input: 1->2->3->4->5, n=2. Length = 5.
Target to skip: 5 - 2 = 3 steps from dummy.
| Steps | Curr | Action |
|---|---|---|
| 0 | Dummy | Move |
| 1 | 1 | Move |
| 2 | 2 | Move |
| 3 | 3 | Stop. curr is now at node 3. curr.next (node 4) is the one to remove. |
curr.next = curr.next.next (node 3 points to node 5) |
⚠️ Common Pitfalls & Tips
You must handle the case where the head itself is removed. Using a dummy node simplifies this.
Level II: Better (Recursion)
Intuition
We can solve this problem recursively by traversing to the end of the list and then backtracking. During backtracking, we keep track of the node count from the end. When it reaches n, we remove the next node.
- Recursively call the function for
head.next. - On return, increment a counter.
- If counter equals
n, the current node'snextshould be skipped.
Detailed Dry Run
Input: 1->2->3, n=1
- Push
1,2,3to stack. - Pop
3, count=1.count == n, so return to2acknowledging3should be removed? (Actually implementation differs slightly).
⚠️ Common Pitfalls & Tips
O(L) space due to recursion might be an issue for very long lists.
Level III: Optimal (One Pass - Two Pointers)
Intuition
Use two pointers, fast and slow. Move fast n steps ahead. Then move both until fast reaches the end. slow will now be just before the node to be removed.
- Initialize
fastandslowpointers at a dummy node. - Move the
fastpointer n+1 steps forward. - Move both pointers together until the
fastpointer reaches the end (null). - At this point,
slow.nextis the node to be removed. Updateslow.next = slow.next.next.
Detailed Dry Run
Input: 1->2->3->4->5, n=2
- Start
fast,slowatdummy. - Move
fast3 steps:fastpoints at 3. - Move both:
fastat 4,slowat 1;fastat 5,slowat 2;fastatnull,slowat 3. slow.next(node 4) is removed.
⚠️ Common Pitfalls & Tips
The gap between fast and slow must be exactly n+1 to land 'slow' on the node before the target.
Visual Representation
List: 1 -> 2 -> 3 -> 4 -> 5, n = 2
[D] -> [1] -> [2] -> [3] -> [4] -> [5] -> null
S,F
1. Move Fast 3 steps (n+1):
[D] -> [1] -> [2] -> [3] -> [4] -> [5]
S F
2. Move both until F is null:
[D] -> [1] -> [2] -> [3] -> [4] -> [5] -> null
S F
3. S.next = S.next.next (skip 4):
[3] -> [5]Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.