Remove Nth Node From End of List
Remove Nth Node From End of List
Section titled “Remove Nth Node From End of List”
Medium
Day 9 • Striver Blind 75
📌 Problem Overview
Section titled “📌 Problem Overview”Given the head of a linked list, remove the nth node from the end of the list and return its head.
Examples & Constraints
Section titled “Examples & Constraints”Example 1:
- Input:
values = [1,2,3,4,5], n = 2 - Output:
[1,2,3,5]
Example 2:
- Input:
values = [1], n = 1 - Output:
[]
Constraints:
The number of nodes is in the range [1, 30]0 ≤ Node.val ≤ 1001 ≤ n ≤ size of the list
💡 Approach & Intuition
Section titled “💡 Approach & Intuition”Remove Nth Node From End tests the two-pointer gap technique to locate a position relative to the end in a single pass, without knowing the list’s length up front.
🎯 Pattern Recognition
Section titled “🎯 Pattern Recognition”Pattern: Two Pointers with a Fixed Gap
Advance one pointer n steps ahead first, then move both together — when the lead pointer hits the end, the trailing pointer is positioned exactly at the target.
📊 Step-by-Step Execution (Mermaid Diagram)
Section titled “📊 Step-by-Step Execution (Mermaid Diagram)”graph LR Head["ListNode (Head)"] --> P1["Pointer 1 (curr / slow)"] Head --> P2["Pointer 2 (prev / fast)"] P1 -->|Iterate / Reverse| Next["Next Node"] P2 -->|Traverse 2x| Next Next --> Verdict["Return Modified Head / Result"]🐢 Brute Force Solution
Section titled “🐢 Brute Force Solution”// Two passes: first count the length, then walk to the node before the targetfunction removeNthFromEnd(values, n) { const dummy = new ListNode(0, buildList(values)); let length = 0; let curr = dummy.next; while (curr) { length++; curr = curr.next; } let prev = dummy; for (let i = 0; i < length - n; i++) prev = prev.next; prev.next = prev.next.next; return toArray(dummy.next);}- Time Complexity:
O(n) - Space Complexity:
O(1) - Explanation: Count the length first, then remove in a second pass.
⚡ Optimized Solution
Section titled “⚡ Optimized Solution”function removeNthFromEnd(values, n) { const dummy = new ListNode(0, buildList(values)); let fast = dummy, slow = dummy; for (let i = 0; i < n; i++) fast = fast.next; while (fast.next) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; return toArray(dummy.next);}- Time Complexity:
O(n) - Space Complexity:
O(1) - Explanation: Single pass with a fixed-gap two-pointer technique.
🐾 Step-by-Step Walkthrough
Section titled “🐾 Step-by-Step Walkthrough”- Initialize State: Setup necessary pointers, dynamic programming arrays, or hash maps.
- Iterate & Evaluate: Process the input according to the boundary conditions.
- Update & Return: Compute the optimal answer and return early or at termination.
🎙️ FAANG Interview Pitch
Section titled “🎙️ FAANG Interview Pitch”- Two-pass approach counts length then removes — simple but two traversals
- One-pass approach keeps a fixed gap of n between two pointers
- A dummy node before head simplifies removing the actual head node
- When fast reaches the last node, slow is right before the node to remove
💡 Progressive Hints
Section titled “💡 Progressive Hints”- Use a dummy node before the head to simplify removing the true head.
- Advance a fast pointer n steps ahead of a slow pointer.
- Move both forward together until fast reaches the last node.