Remove Nth Node from End of List in DSA Typescript - Time & Space Complexity
We want to understand how the time needed changes when we remove the nth node from the end of a linked list.
How does the work grow as the list gets longer?
Analyze the time complexity of the following code snippet.
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
let fast = head;
let slow = head;
for (let i = 0; i < n; i++) {
if (fast) fast = fast.next;
}
if (!fast) return head ? head.next : null;
while (fast.next) {
fast = fast.next;
slow = slow ? slow.next : null;
}
if (slow && slow.next) slow.next = slow.next.next;
return head;
}
This code removes the nth node from the end by using two pointers moving through the list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Two loops moving pointers through the list.
- How many times: The first loop runs n times, the second loop runs (length - n) times.
As the list gets longer, the total steps grow roughly with the list size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The work grows linearly as the list size increases.
Time Complexity: O(n)
This means the time to remove the node grows in direct proportion to the list length.
[X] Wrong: "Since we only move pointers a few times, the time is constant O(1)."
[OK] Correct: The pointers must move through the list nodes, which depends on the list length, so time grows with n.
Understanding this helps you handle linked list problems efficiently, a common skill interviewers look for.
"What if we used recursion instead of two pointers? How would the time complexity change?"
Practice
Remove Nth Node from End of List ask you to do?Solution
Step 1: Understand the problem statement
The problem requires removing the node that is nth from the end of a singly linked list.Step 2: Clarify the task
We do not add or reverse nodes; we specifically remove the nth node counting from the list's end.Final Answer:
Delete the node that is the nth from the end in a linked list -> Option DQuick Check:
Remove nth from end = Delete nth from end [OK]
- Confusing nth from end with nth from start
- Thinking the problem is about reversing the list
- Assuming insertion instead of deletion
Solution
Step 1: Check parameter types and order
The function should take the head of a linked list (ListNode or null) and a number n, returning the possibly updated head.Step 2: Validate correct types and order
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null matches this: head is ListNode|null, n is number, return type is ListNode|null.Final Answer:
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null -> Option CQuick Check:
Correct signature uses ListNode and number types [OK]
- Swapping parameter order
- Using array type instead of ListNode
- Using wrong type for n (string instead of number)
1 -> 2 -> 3 -> 4 -> 5 -> null?Solution
Step 1: Identify the 2nd node from the end
Counting from the end: 5 is 1st, 4 is 2nd node from the end.Step 2: Remove the 4th node
Removing node with value 4 results in list: 1 -> 2 -> 3 -> 5 -> null.Final Answer:
1 -> 2 -> 3 -> 5 -> null -> Option BQuick Check:
2nd from end is 4, removed list matches 1 -> 2 -> 3 -> 5 -> null [OK]
- Removing wrong node counting from start
- Removing node 3 instead of 4
- Confusing 2nd from end with 2nd from start
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
let fast = head;
let slow = head;
for (let i = 0; i < n; i++) {
fast = fast.next;
}
while (fast.next !== null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}Solution
Step 1: Analyze fast pointer movement
Fast pointer moves n steps ahead. If n equals list length, fast becomes null.Step 2: Check while loop condition
Code uses fast.next, but if fast is null, accessing fast.next causes error or skips removing head.Step 3: Identify missing edge case handling
Code does not handle removing the first node when n equals list length.Final Answer:
It does not handle the case when n equals the length of the list -> Option AQuick Check:
Edge case n = list length missing [OK]
- Ignoring edge case when removing head node
- Assuming fast.next always exists
- Not returning updated head when head is removed
1 -> 2 -> 3 -> 4 -> 5 -> null. You remove the 5th node from the end twice in a row. What is the final linked list?Solution
Step 1: First removal of 5th node from end
List length 5, 5th from end is head (1). After removal: 2 -> 3 -> 4 -> 5 -> null.Step 2: Second removal of 5th node from end
New length 4, n=5 > 4 so no 5th node exists; list unchanged: 2 -> 3 -> 4 -> 5 -> null.Final Answer:
2 -> 3 -> 4 -> 5 -> null -> Option AQuick Check:
Removing 5th from end twice removes head once [OK]
- Confusing nth from end with nth from start
- Thinking the problem is about reversing the list
- Assuming insertion instead of deletion
Ready to prove it?
Pass the test and this pattern moves unknown
