Remove Nth Node From End of List
The drill: Remove the node that sits n positions from the end of a singly linked list — measured from the tail, not the head — and hand back the list with that one node gone.
A singly linked list and a whole number n arrive together, and the job is to remove whichever node sits n positions back from the very end of the list — counting from the tail, not the head.
After that one node is unlinked, the rest of the list keeps its original order and wiring, and the new head is handed back — which might be a different node than before if the removed node was the original head.
n is always small enough to point at a real node somewhere in the list, so there's never a question of the target falling outside the list's bounds.
- list holds up to a few thousand nodes
- n always refers to a real, in-bounds node, counted from the tail
- removing the head node is a valid case that changes what's returned
- only one node is removed, everything else keeps its order
HINT 1 THE NUDGE
Copying every value out, deleting the one at the target offset, and rebuilding the list from what's left is honest and correct — but it never reuses a single original node. Could two pointers moving a fixed distance apart find the target using only the nodes you already have?
HINT 2 THE STRUCTURE
A pointer that starts n steps ahead of a second pointer keeps that exact gap for the rest of the walk. When the lead pointer reaches the last node, where does the trailing pointer have to be sitting?
HINT 3 ONE STEP FROM THE ANSWER
Run a pointer n steps out from a dummy head, then advance it and a second pointer from the dummy together until the leader falls off the end — the trailer is now parked exactly one node before the target, ready to unlink it.
Remove the node 2 from the end of [1, 2, 3, 4, 5] — that's the node holding value 4. A fixed gap between two pointers finds it in one pass.
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(0, head)
fast = slow = dummy
for _ in range(n):
fast = fast.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.nextclass Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
vals = []
node = head
while node:
vals.append(node.val)
node = node.next
del vals[len(vals) - n]
dummy = ListNode(0)
tail = dummy
for v in vals:
tail.next = ListNode(v)
tail = tail.next
return dummy.nextclass 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++) fast = fast.next;
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
List<Integer> vals = new ArrayList<>();
for (ListNode node = head; node != null; node = node.next) vals.add(node.val);
vals.remove(vals.size() - n);
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
for (int v : vals) {
tail.next = new ListNode(v);
tail = tail.next;
}
return dummy.next;
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED