Laki
Laki Technology enthusiast

Leetcode problem 19 - Remove Nth Node From End of List | Problem and solution

Leetcode problem 19 - Remove Nth Node From End of List | Problem and solution

Remove Nth Node From End of List

Description

Given the head of a linked list, remove the nth node from the end of the list and return its head.

Example 1:

1
2
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]

Example 2:

1
2
Input: head = [1], n = 1
Output: []

Example 3:

1
2
Input: head = [1,2], n = 1
Output: [1]

Solutions

Brute-Force Solution (Two Passes)

The simplest idea is to first determine the length of the linked list. Once we know the total number of nodes, we can compute the position to remove from the start of the list (which is length - n). Then we walk the list again to reach that node and adjust pointers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        int length = 0;
        ListNode temp = head;
        // First pass to count the nodes
        while (temp != null) {
            length++;
            temp = temp.next;
        }
        // If we need to remove the first node
        if (n == length) return head.next;

        temp = head;
        // Second pass to reach the node before the one we want to remove
        for (int i = 1; i < length - n; i++) {
            temp = temp.next;
        }
        temp.next = temp.next.next;
        return head;
    }
}

Time Complexity: O(2n) Space Complexity: O(1) Pros: Easy to understand Cons: Requires two passes through the list

One-Pass Solution Using Two Pointers

To improve performance, we can remove the need for two full passes using the two-pointer technique — sometimes also referred to as the fast and slow pointer method.

We start both pointers at a dummy node before the head. We move the fast pointer n steps ahead. Then, we move both pointers one step at a time until the fast pointer reaches the end. The slow pointer will then be right before the node to delete.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode fast = dummy;
        ListNode slow = dummy;

        // Move fast ahead by n steps
        for (int i = 0; i < n; i++) {
            fast = fast.next;
        }

        // Move both fast and slow until fast reaches the end
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        // Skip the target node
        slow.next = slow.next.next;

        return dummy.next;
    }
}

Time Complexity: O(n) Space Complexity: O(1) Pros: Single traversal, efficient Cons: Slightly more setup with dummy node and edge case handling

Edge Case: Deleting the First Node

You may run into a case where the node to be deleted is the very first one. The above code already handles it using a dummy node, but if you’d like to write an explicit check:

1
2
3
if (fast.next == null) {
    return head.next;
}

This condition checks whether the list size equals n, meaning we need to remove the head.

Final Thoughts

This is a classic interview question that tests your understanding of linked list traversal and pointer manipulation. While the brute-force approach is fine for learning, the one-pass method is preferred in real-world scenarios due to its efficiency.

comments powered by Disqus