LeetCode ยท #19

Remove Nth Node From End of List Solution

Given the head, remove the nth node from the end and return the head.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Medium

๐Ÿ”—

LeetCode

Problem #19

๐Ÿ—๏ธ

Pattern

Two Pointers โ€” n-gap technique

Given the head of a linked list, remove the nth node from the end of the list and return its head.

Example
Input: 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5, n = 2 Output: 1 โ†’ 2 โ†’ 3 โ†’ 5 // Removed node 4 (2nd from end)
Constraints
โ€ข 1 โ‰ค sz โ‰ค 30 โ€ข 0 โ‰ค Node.val โ‰ค 100 โ€ข 1 โ‰ค n โ‰ค sz
02
Section Two ยท Approach 1

Two Pass โ€” O(n)

First pass: count the total length L. Second pass: advance L-n steps to the node before the target, then skip over it. Two traversals.

Can we do it in one pass? Yes โ€” the n-gap technique uses two pointers separated by n nodes. When the leading pointer reaches the end, the trailing pointer is at the node before the target.
03
Section Three ยท Approach 2

One-Pass Two Pointers โ€” O(n)

Advance a fast pointer n steps ahead. Then move both fast and slow together. When fast reaches the end, slow is right before the target node. Delete by slow.next = slow.next.next.

๐Ÿ’ก Mental model: Imagine two people walking in a hallway, n steps apart. When the leader reaches the wall, the follower is exactly n steps from the wall โ€” standing right before the node you want to remove.
Algorithm
  • Step 1: Create a dummy node pointing to head (handles edge case of removing head).
  • Step 2: fast = dummy, slow = dummy. Advance fast n+1 steps.
  • Step 3: Move both until fast reaches null.
  • Step 4: slow.next = slow.next.next (delete target).
  • Step 5: Return dummy.next.
๐ŸŽฏ Why a dummy node?:
  • If we're removing the head (n == list length), there's no node before the head.
  • A dummy node before head gives us something to link from.
  • Without it, we'd need a special case for removing the first node.
04
Section Four ยท Trace

Visual Walkthrough

Trace: 1โ†’2โ†’3โ†’4โ†’5, n=2:

N-gap two pointers โ€” fast leads by n+1
LIST: dummy โ†’ 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ null n=2 D โ†’ 1 โ†’ 2 โ†’ 3 โ†’ 4 โ† remove โ†’ 5 PHASE 1: Advance fast by n+1 = 3 steps fast: D โ†’ 1 โ†’ 2 โ†’ 3 slow stays at dummy. Gap = 3 nodes. PHASE 2: Move both until fast = null slow=1, fast=4 โ†’ slow=2, fast=5 โ†’ slow=3, fast=null โ†’ STOP PHASE 3: Skip slow.next (node 4) slow=3 โ†’ slow.next = slow.next.next โ†’ 3.next = 5 (skip 4) RESULT 1 โ†’ 2 โ†’ 3 โ†’ 5 Answer: 1โ†’2โ†’3โ†’5 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” One-pass with dummy
class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0, head); ListNode fast = dummy, slow = dummy; for (int i = 0; i <= n; i++) // n+1 steps fast = fast.next; while (fast != null) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; // delete target return dummy.next; } }
Python โ€” One-pass with dummy
class Solution: def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: dummy = ListNode(0, head) fast = slow = dummy for _ in range(n + 1): fast = fast.next while fast: fast = fast.next slow = slow.next slow.next = slow.next.next return dummy.next
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Two PassO(n)O(1)Count then remove โ€” two traversals
One Pass โ† optimal O(n) O(1) Single traversal, n-gap pointers
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
Remove head[1], n=1Only node โ†’ remove it โ†’ return null. Dummy handles this.
Remove first node[1,2], n=2n == length. slow stays at dummy โ†’ dummy.next = 2.
Remove last[1,2,3], n=1slow ends at node 2, skips node 3.
โš  Common Mistake: Advancing fast only n steps instead of n+1. We need slow to land one node before the target so we can skip it. With n steps, slow lands at the target โ€” too late to delete it.

โ† Back to Linked List problems