Sweaty Imposter

Remove Nth Node From End of List

MediumLinked ListBlind 75MidOpen on LeetCodeUpdated

You're given the head of a singly linked list and an integer n. Remove the n-th node counting from the end of the list, where n = 1 means the last node, and return the head of the resulting list. n is always between 1 and the list's length, so the node to remove can be the head itself. Try to do it in a single pass, without first counting the length.

Examples

head = [1,2,3,4,5], n = 2 returns [1,2,3,5]

12345null
4 is the 2nd node from the end, so it goes.

Counting from the end, 5 is 1st and 4 is 2nd, so 4 is removed and 3 now links straight to 5.

head = [1], n = 1 returns []

The only node is also the last one, so removing it leaves an empty list.

head = [1,2], n = 1 returns [1]

n = 1 means the last node, 2, is removed and 1 becomes the tail.

Constraints

  • The number of nodes in the list is sz.
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

Hints

Hint 1

If a marker trails a runner by a fixed number of nodes, where is the marker when the runner reaches the end?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Start two pointers, lead and follow, at a dummy node placed before head. Move lead n steps so it is n nodes ahead of follow, then advance both together until lead is on the last node. follow now sits just before the n-th node from the end, so follow.next = follow.next.next unlinks it. The dummy makes removing the head an ordinary case. One pass: O(L) time and O(1) space, where L is the list length.

Time

O(L)

Space

O(1)

Pitfall

Removing the head (n equal to the length) breaks solutions without a dummy node, since there is no previous node to relink. Looping until lead is null instead of until lead.next is null leaves follow on the target instead of just before it.

Solutions

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0, head);
        ListNode lead = dummy, follow = dummy;
        for (int i = 0; i < n; i++) lead = lead.next;
        while (lead.next != null) {
            lead = lead.next;
            follow = follow.next;
        }
        follow.next = follow.next.next;
        return dummy.next;
    }
}
Drill This