intermediate8 min read·Updated September 23, 2026

Remove Nth Node from End Explained: Deleting 4 & Head from 1-5

Master linked list deletion in a single pass. Step-by-step walkthrough of removing n=2 and n=5 (head) from 1→2→3→4→5 using the two-pointer mental model.

By Learnisim AI·Published September 23, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • Basic pointer manipulation in linked lists
  • Understanding of singly linked list traversal
Remove Nth Node from End (Single-Pass Two-Pointer Gap) Example: n=2 from 1 → 2 → 3 → 4 → 5 (Deletes node 4) dummy 0 node 1 1 node 2 2 node 3 3 target 4 node 5 5 null slow fast (end) gap = n+1 (3) slow.next = next.next 1 Initialize & Head Start • Create dummy node (val=0). • slow = fast = dummy. • Sprint fast forward by n+1 steps (3 steps for n=2). Why n+1 gap? Ensures slow lands exactly 1 node BEFORE the deletion target. 2 Lockstep Advance • Move both pointers together one step at a time. • Maintain constant gap of n+1 throughout the entire list. Single-Pass Magic When fast hits null, slow is perfectly positioned! 3 Splice & Head Edge Case • Execute: slow.next = slow.next.next • Returns dummy.next safely. What if n = list length? Dummy node absorbs head deletion (e.g., n=5 deletes head node 1).
Remove n=2 from 1→2→3→4→5, then n=5 (the head) overview diagram
Why

Why Single-Pass Linked List Deletion Is Unintuitively Tricky

Phase 1: The Length Trap

Imagine you are given the linked list Given: 1 -> 2 -> 3 -> 4 -> 5 and asked to Remove n=2 from end, which means deleting node 4 to leave 1 -> 2 -> 3 -> 5. Your first instinct might be straightforward: walk through the entire list once to count its total nodes, subtract from that total length to find the target's forward index, and then walk through the list a second time to perform the splice. But what happens if the requirements demand a single pass?
In data stream or strict performance contexts, iterating twice is inefficient or impossible. Yet, if you only move forward pointer-by-pointer, you do not know when you are nodes away from the end because you cannot see the future. If you start deleting blindly, you might overshoot or undershoot the target node entirely. The core challenge of Remove Nth node from end of list explained is figuring out how to measure distance from a finish line that you haven't reached yet.
To make matters worse, consider the second part of our challenge: then n=5 (the head). Here, equals the exact length of the list, meaning you must delete the very first node (1), resulting in 2 -> 3 -> 4 -> 5. Without a strategy to handle the structural edge case where the head itself gets chopped, a naive single-pass loop will crash or corrupt pointer references. We need a way to orchestrate pointers so they naturally land right before our target without ever counting nodes.
Why Single-Pass Linked List Deletion Is Unintuitively Tricky Phase 1: Two-Pointer Gap Technique (Remove n=2 from end) Dummy 1 2 3 4 5 SLOW FAST Gap = n (2) Why the Gap Works in One Pass: 1. Advance FAST pointer n steps ahead first. 2. Move both FAST and SLOW in sync. 3. When FAST hits null, SLOW stops before target! Phase 2: The Head Deletion Edge Case (When n = List Length) Dummy 1 2 3 4 5 SLOW (Dummy) FAST Why Dummy Node Prevents Crashes: • If n equals list length, target is the head node (1). • Without dummy, SLOW would fall off start. • Dummy anchors SLOW before head so Dummy.next safely bypasses the deleted head! 1. Dummy Node Sentinel Always prepend dummy -> head. Guarantees valid predecessor pointer. 2. Advance Fast Pointer Loop n times from dummy. Establishes exact n-node distance gap. 3. Single-Pass Sweep & Splice Step both until fast reaches end. Execute: slow.next = slow.next.next
Why Single-Pass Linked List Deletion Is Unintuitively Tricky diagram
Model

Two Pointers, One Gap: The Two-Pointer Model

How do we delete an item from the end of a singly linked list without counting its total nodes first? The secret is a fixed-offset race between two markers: a fast pointer and a slow pointer. Imagine two runners on a track separated by a constant head start of steps. When the lead runner hits the finish line (null), the trailing runner is mathematically guaranteed to be standing right before the target node that needs removal.
For our locked example where the list is and we want to remove , the gap between our pointers must be steps. If we introduce a dummy node at the start—making our chain —both runners begin safely behind the real head. The fast pointer sprints ahead by 3 nodes before anyone else moves. Then, both fast and slow pointers advance together one step at a time until the fast pointer reaches the end of the list. At that exact moment, the slow pointer rests precisely on the node preceding our target 4, ready to execute a pointer bypass.
Two Pointers, One Gap: Remove N-th Node from End (n=2) Linked List State: Dummy → 1 → 2 → 3 → 4 → 5 → NULL Bypass Target (Node 4) dummy 1 2 3 4 5 NULL SLOW ptr FAST ptr 1 Establish Gap • Formula: gap = n + 1 steps • For n = 2, gap = 3 nodes. • Fast pointer sprints ahead by 3 nodes from dummy. Gap maintains constant offset 2 Race Together • Advance both pointers at the exact same speed. • Fast pointer hits NULL at end of the list. Slow lands at Target - 1 3 Bypass & Delete • Slow pointer is right before target node (Node 4). • Update pointer linkage: slow.next = slow.next.next Target 4 is safely garbage-collected
Two Pointers, One Gap: The Two-Pointer Model diagram
Worked example

Tracing the Two-Pointer Gap on a Concrete List

Phase 3: Worked Example

To see the gap model in action, let us trace our locked example: with . We want to delete the node with value 4, which is the second node from the end.
Given:
- head:
-
- dummy:
Steps:
1. Initialize pointers at dummy: Both fast and slow point to the dummy node ().
2. Advance fast by steps:
- Step 1: fast moves to node 1
- Step 2: fast moves to node 2
- Step 3: fast moves to node 3
- Current state: slow is at dummy (0), fast is at node 3. The gap between them is exactly 3 nodes ().
3. Advance both fast and slow in lockstep until fast reaches null:
- Iteration 1: fast moves to node 4, slow moves to node 1.
- Iteration 2: fast moves to node 5, slow moves to node 2.
- Iteration 3: fast moves to null, slow moves to node 3.
4. Perform deletion: slow.next currently points to node 4. We update slow.next = slow.next.next, which links node 3 directly to node 5.
Result:
The modified list is , successfully omitting node 4.
Try this: dummy = Node(0, head)
slow = fast = dummy
for _ in range(n + 1):
fast = fast.next
while fast:
slow = slow.next
fast = fast.next
slow.next = slow.next.next
Phase 3: Worked Example — Tracing n = 2 on List [1, 2, 3, 4, 5] Goal: Advance fast by n+1 (3 steps), then march in lockstep until fast reaches null 0 dummy 1 node 1 2 node 2 3 node 3 4 target 5 node 5 null slow fast slow.next = slow.next.next Execution Trace Summary (n = 2): 1. Initialize: slow & fast start at dummy (node 0). 2. Advance fast by n+1 = 3 steps (fast lands on node 3). Gap established! 3. Lockstep march: when fast hits null, slow rests at node 3 $ ightarrow$ bypass node 4 directly to node 5.
Tracing the Two-Pointer Gap on a Concrete List diagram
Practice

Predicting the Gap and Pointer Positions for Edge Deletions

Phase 4: Practice

Now that you have seen how the gap handles standard nodes like in , it is time to test your mental model on the second part of our locked example: removing (the entire length of the list, which means deleting the head node 1).
Before jumping to the full solution, trace through what happens when the fast pointer advances steps (which is steps) from the dummy node:
1. Start with dummy .
2. Advance fast pointer 6 total steps forward.
3. Keep slow stationary at dummy during this initial advance phase.

The Task

Answer the following question about pointer positions and node mutations for this head deletion task.
Apply

Transferring the Fixed-Gap Pattern to Circular List Removal

Phase 5: Transfer

Now that you have mastered the dual-pointer gap mechanics for our working example of (removing and the head ), let us apply this exact structural pattern to a new scenario. Suppose you are given a singly linked list that you suspect might contain a cycle, but your primary constraint is that you must find the start of the cycle in extra space and without computing the length beforehand.
Just as the gap in our base problem let us locate the target node without counting the total nodes, Floyd's Cycle-Finding Algorithm uses two pointers moving at different speeds to discover a cycle invariant. The underlying mental model remains identical: create a deterministic spatial offset between two traversal tokens so that their intersection point reveals topological metadata (the end-of-list boundary in our list removal, versus the cycle entry node in the loop detection).
python
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def detectCycleStart(head: ListNode) -> ListNode:
    # Apply the pointer-offset mental model here:
    # 1. Detect if a cycle exists using fast/slow pointers
    # 2. Reset one pointer to head and find the entry node
    pass

FAQ

How do we remove node n=2 from 1→2→3→4→5 using the two-pointer approach?
We set up a fixed gap of n+1 (3 nodes) between a fast pointer and a slow pointer. Advancing fast to the end leaves slow right before the target node (4), allowing us to bypass it and result in 1→2→3→5.
What happens when n equals the length of the list, such as removing n=5 from 1→2→3→4→5?
When n equals the list length, the fast pointer reaches the end when the gap spans the entire list, landing us on the head node. By using a dummy node before the head, we safely delete the head, resulting in 2→3→4→5.
Why use a dummy node for this algorithm?
A dummy node pointing to the head ensures that edge cases—like deleting the head of the list—are handled uniformly, as the slow pointer will always have a valid preceding node to modify.
What is the time and space complexity of removing the nth node from the end?
The time complexity is O(L) where L is the number of nodes in the list, requiring only a single pass. The space complexity is O(1) because we only use a few pointer variables.

Keep learning