Remove Nth Node From End of List

MediumLinked List · Fast & Slow Pointers🧩 Linked List TechniquesLeetCode #19 ↗Updated

Problem

Given the head of a singly linked list and an integer n, unlink the node that is n-th from the end (n = 1 is the last node) and return the head of the resulting list — which changes if the first node is removed.
Inputhead=[1,2,3,4,5], n=2Output[1,2,3,5]
Inputhead=[1], n=1Output[]
Inputhead=[1,2], n=2Output[2]

1 ≤ L ≤ 30  ·  0 ≤ Node.val ≤ 100  ·  1 ≤ n ≤ L  ·  Follow-up: one pass.

Try it yourself

Java
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Keep a fixed gap: if fast starts n+1 nodes ahead of slow, then when fast runs off the end, slow sits right before the target. A dummy head makes removing the first node a non-special case.
PatternLinked List Techniques

Instinct Nodes joined by next pointers and the task is to reverse, splice, merge, reorder or remove in place - grab a dummy head and rewire pointers carefully.

Memory hack Save next, flip, step - never let go of a rope before you've grabbed the next one.

Open the Linked List Techniques guide →

Approaches

Brute ForceArray of Node References

Time O(L)Space O(L)

Copy every node reference into an ArrayList to get random access. The target is at index L-n; relink its predecessor, or return head.next when the target is the head.

Java
public ListNode removeNthFromEnd(ListNode head, int n) {
    List<ListNode> nodes = new ArrayList<>();
    for (ListNode c = head; c != null; c = c.next) nodes.add(c);
    int idx = nodes.size() - n;       // index of node to remove
    if (idx == 0) return head.next;
    nodes.get(idx - 1).next = nodes.get(idx).next;
    return head;
}

One traversal and trivial indexing, but O(L) extra memory.

At a glance

LevelApproachTimeSpace
Brute ForceArray of Node ReferencesO(L)O(L)
BetterTwo Passes (Count, then Walk)O(L)O(1)
OptimalOne Pass — Gap of n+1O(L)O(1)
Common pitfalls
  • No dummy node — n == L (remove head) crashes or needs a special case.
  • Advancing fast only n steps — slow lands on the target, not before it.
  • Returning head instead of dummy.next after the head was removed.
Interview tips
  • Ask whether n is always valid (here 1 ≤ n ≤ L).
  • Explain the gap invariant rather than just the code.
  • Note both O(1) versions are O(L); one pass matters for streams or huge lists.
Pattern
Fixed-gap two pointers → locate the k-th node from the end of a list in one pass.
My notes saved in this browser