19. Remove Nth Node From End of List - Detailed Explanation
Problem Statement
Description:
Given a singly linked list, remove the nth node from the end of the list and return its head. You are guaranteed that n is valid, meaning that the linked list contains at least n nodes.
Examples:
-
Example 1:
- Input: head = [1, 2, 3, 4, 5], n = 2
- Output: [1, 2, 3, 5]
- Explanation: The second node from the end is the node with value 4. Removing it results in the list [1, 2, 3, 5].
-
Example 2:
- Input: head = [1], n = 1
- Output: []
- Explanation: Removing the only node in the list yields an empty list.
-
Example 3:
- Input: head = [1, 2], n = 1
- Output: [1]
- Explanation: Removing the last node (node with value 2) results in the list [1].
Constraints:
- The number of nodes in the list is between 1 and 30.
- 1 ≤ n ≤ number of nodes in the list.
Hints Before the Solution
-
Two-Pointer Technique:
Use a fast pointer and a slow pointer. Move the fast pointer n steps ahead of the slow pointer so that when the fast pointer reaches the end, the slow pointer is right before the node you need to remove. -
Dummy Node:
To simplify edge cases (like removing the head of the list), create a dummy node that points to the head. This ensures that every node has a previous node.
Approaches
Approach 1: Two-Pass Solution
Idea:
- First Pass: Traverse the linked list to count the total number of nodes.
- Second Pass: Compute the position of the node to remove from the start (which is
totalNodes - n
) and traverse again to that position, then adjust the pointers to remove the target node.
Pros:
- Easy to understand and implement.
Cons:
- Requires two traversals of the linked list.
Approach 2: Optimal One-Pass Solution Using Two Pointers
Idea:
-
Initialization: Create a dummy node pointing to the head. Set two pointers,
fast
andslow
, both starting at the dummy. -
Advance Fast Pointer: Move the fast pointer n+1 steps forward. This ensures that the gap between
fast
andslow
is n nodes. -
Simultaneous Movement: Move both pointers one step at a time until the fast pointer reaches the end. At that point, the slow pointer will be just before the node that needs to be removed.
-
Remove Node: Adjust
slow.next
to skip the target node.
Pros:
- Only one pass through the list is needed.
- Handles edge cases smoothly with the dummy node.
Cons:
- Requires careful pointer management.
Code Implementations
Python Implementation
Java Implementation
Complexity Analysis
-
Time Complexity:
-
Both approaches require a single pass (or two passes in the simpler approach) through the list.
-
Let L be the number of nodes. The one-pass solution runs in O(L) time.
-
-
Space Complexity:
- The solution uses a few pointers and a dummy node, so the space complexity is O(1).
Step-by-Step Walkthrough with Visual Example
Consider the list: [1, 2, 3, 4, 5] and n = 2.
-
Initialization:
- Create a dummy node that points to the head: dummy -> 1 -> 2 -> 3 -> 4 -> 5.
- Set both
fast
andslow
pointers at the dummy node.
-
Advance Fast Pointer:
- Move fast pointer n+1 = 3 steps ahead:
- Step 1: fast points to node 1.
- Step 2: fast points to node 2.
- Step 3: fast points to node 3.
- Move fast pointer n+1 = 3 steps ahead:
-
Simultaneous Movement:
- Move both pointers until
fast
reaches the end:- Move 1: fast -> 4, slow -> 1.
- Move 2: fast -> 5, slow -> 2.
- Move 3: fast -> null, slow -> 3.
- Move both pointers until
-
Removal:
- Now, slow is just before the node to remove (node with value 4).
- Adjust pointers: set slow.next = slow.next.next, effectively skipping node 4.
- Final list becomes: [1, 2, 3, 5].
Common Mistakes
-
Not Using a Dummy Node:
Failing to use a dummy node may lead to errors when removing the head node. -
Incorrect Pointer Advances:
Ensure that the fast pointer is moved exactly n+1 steps ahead so that the gap is maintained correctly. Missing or extra steps can lead to off-by-one errors. -
Edge Cases Overlooked:
Always consider edge cases, such as a single-node list or when the head is the node to be removed.
Edge Cases
-
Single Node List:
Removing the only node should return an empty list. -
Removing the Head Node:
When n equals the length of the list, the head node is removed. The dummy node handles this gracefully. -
Minimal List Length with n = 1:
Removing the last node in a two-node list, ensuring the remaining node is correctly returned.
Alternative Variations and Related Problems
-
Alternative Variation:
Modify the problem to remove the nth node from the start instead of the end. This can be done with a single traversal without the two-pointer technique. -
Related Problems for Further Practice:
-
Reverse Linked List
-
Merge Two Sorted Lists
-
Linked List Cycle
-
Intersection of Two Linked Lists
-
Palindrome Linked List
-
GET YOUR FREE
Coding Questions Catalog