Remove N-th Node From End of List in C#
1. The Problem: Remove N-th Node From End of List
Given the head of a linked list, remove the n-th node from the end of the list and return its head.
Example 1:
- Input:
head = [1,2,3,4,5],n = 2 - Output:
[1,2,3,5]
Example 2:
- Input:
head = [1],n = 1 - Output:
[]
Example 3:
- Input:
head = [1,2],n = 1 - Output:
[1]
2. The Intuition: Two-Pointer Technique
The most efficient way to solve this problem is by using two pointers, often called fast and slow, in a single pass.
The goal is to position the slow pointer at the node just before the one we want to remove. To do this:
- Move the
fastpointernsteps ahead. - Move both
fastandslowpointers together untilfastreaches the last node. - The
slowpointer will now be exactlynnodes behindfast, which means it’s pointing to the node preceding the target.
To handle the edge case where we need to remove the first node (the head), we use a dummy node that points to the head.
Logic Steps:
- Initialize Dummy: Create a
dummynode withnextpointing tohead. - Initialize Pointers: Set both
slowandfastpointers to thedummynode. - Advance Fast Pointer: Move
fastforwardntimes. - Traverse Together: While
fast.nextis not null, move bothslowandfastforward one step at a time. - Remove Node: Update
slow.nextto skip the target node:slow.next = slow.next.next. - Return Result: Return
dummy.next(the new head).
3. Solution: Two-Pointer Approach
Here is the implementation in C#:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode RemoveNthFromEnd(ListNode head, int n) {
// Use a dummy node to simplify edge cases (e.g., removing the head)
ListNode dummy = new ListNode(-1, head);
ListNode slow = dummy;
ListNode fast = dummy;
// Move fast pointer n steps ahead
while (n > 0 && fast.next != null) {
fast = fast.next;
n -= 1;
}
// Move both pointers until fast reaches the end
while (fast.next != null) {
slow = slow.next;
fast = fast.next;
}
// slow is now just before the node to be removed
slow.next = slow.next.next;
return dummy.next;
}
}
4. Complexity Analysis
| Approach | Time Complexity | Space Complexity | Why? |
|---|---|---|---|
| Two-Pointer | O(N) |
O(1) |
Single pass through the list, constant extra space for pointers. |
- Time Complexity:
O(N), where N is the number of nodes in the linked list. We traverse the list once. - Space Complexity:
O(1), as we only use a few extra pointer variables regardless of the list size.
5. Summary
Using the two-pointer technique allows us to solve this problem in a single pass with constant space. The dummy node is a crucial pattern in linked list problems as it gracefully handles cases where the head of the list might be modified or removed.
Leave a comment