01
Problem Statement
Given the head of a linked list, remove the n-th node from the end of the list and return its head. Assume n is valid (1-indexed from the end). Try to do this in one pass.
- The n-th node from the end is the node such that there are
n-1nodes after it. So we need to find the node at position(length - n)from the start (0-indexed) and remove it. - Using a dummy node before
headsimplifies the case when we remove the head (n = length).
02
Key Observations
- Two pointers with gap: Place
fastandslowso thatfastisn+1steps ahead ofslow. Whenfastreachesnull(past the last node),slowis at the node before the one to remove. So we setslow.next = slow.next.next. - Use a dummy node:
dummy.next = head. Startfast = dummyand movefastforwardn+1times (so the gap betweenslowandfastisn+1whenslow = dummy). Then move both untilfast == null.slow.nextis the n-th from the end; remove it.
03
Approach
High-level: Dummy node before head. Move fast from dummy forward n+1 times. Then move slow and fast together until fast == null. slow is the predecessor of the node to remove; set slow.next = slow.next.next. Return dummy.next.
Steps:
ListNode dummy = new ListNode(0); dummy.next = head;fast = dummy; movefastforwardn+1times (for loop).slow = dummy. Whilefast != null:fast = fast.next,slow = slow.next.slow.next = slow.next.next. Returndummy.next.
04
Implementation
Java
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy, slow = dummy;
for (int i = 0; i <= n; i++) {
fast = fast.next;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}05
Test Cases
Example 1
Input
head = [1,2,3,4,5], n = 2
Expected
[1,2,3,5]Explanation
Remove 4.
06
Complexity Analysis
- Time: O(n).
- Space: O(1).
07
Follow-ups
- One pass without dummy: handle n==length separately.