Remove Nth Node From End Of List
Remove Nth Node From End Of List#
Problem#
Given the head of a singly linked list and an integer n, remove the n-th
node counting from the end of the list, then return the head. It is
guaranteed that n is valid for the list length.
Example#
List 1 -> 2 -> 3 -> 4 -> 5 with n = 2 removes node 4, giving
1 -> 2 -> 3 -> 5. With n = 1 on a single-node list, the result is empty.
Brute force#
First walk the list to count its length L, then walk again to the node at
position L - n and unlink it. That is two passes.
Optimal approach#
Do it in one pass with two pointers and a dummy head that handles the case of
removing the actual first node. Advance a fast pointer n steps ahead of a
slow pointer that starts at the dummy. Then move both together until fast
reaches the end. At that moment slow sits on the node just before the target,
so slow.next = slow.next.next unlinks it. Return dummy.next.
Solution#
1class ListNode:
2 def __init__(self, val=0, next=None):
3 self.val = val
4 self.next = next
5
6
7def remove_nth_from_end(head: ListNode | None, n: int) -> ListNode | None:
8 dummy = ListNode(0, head)
9 fast = slow = dummy
10 for _ in range(n):
11 fast = fast.next
12 while fast.next:
13 fast = fast.next
14 slow = slow.next
15 slow.next = slow.next.next
16 return dummy.next
17
18
19def build(values):
20 head = None
21 for value in reversed(values):
22 head = ListNode(value, head)
23 return head
24
25
26def to_list(node):
27 out = []
28 while node:
29 out.append(node.val)
30 node = node.next
31 return out
32
33
34print(to_list(remove_nth_from_end(build([1, 2, 3, 4, 5]), 2))) # [1, 2, 3, 5]
35print(to_list(remove_nth_from_end(build([1]), 1))) # []
Complexity#
- Time: O(n), a single pass.
- Space: O(1).
This applies the fast and slow pointers gap technique. Continue with the 60-day challenge.