Remove Nth Node from End of List in DSA Python - Time & Space Complexity
We want to understand how the time needed to remove the nth node from the end of a linked list changes as the list grows.
Specifically, how many steps does the program take when the list gets longer?
Analyze the time complexity of the following code snippet.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def removeNthFromEnd(head: ListNode, n: int) -> ListNode:
fast = slow = head
for _ in range(n):
fast = fast.next
if fast is None:
return head.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return head
This code removes the nth node from the end of a singly linked list by using two pointers moving through the list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Moving pointers through the linked list nodes.
- How many times: The first loop moves the fast pointer n times; the second loop moves both pointers until the fast pointer reaches the end, which can be up to (length - n) times.
As the list size grows, the number of steps to move pointers grows roughly in proportion to the list length.
| Input Size (length) | Approx. Operations |
|---|---|
| 10 | About 10 steps to move pointers |
| 100 | About 100 steps to move pointers |
| 1000 | About 1000 steps to move pointers |
Pattern observation: The steps increase linearly as the list size increases.
Time Complexity: O(n)
This means the time to remove the nth node from the end grows linearly with the list size.
[X] Wrong: "Since we only move the fast pointer n times first, the time complexity is O(n) where n is the given number, not the list size."
[OK] Correct: The second loop moves pointers through the rest of the list, which depends on the total list length, not just the given n. So the total steps depend on the list size.
Understanding this helps you explain how to efficiently find and remove nodes from linked lists, a common task in coding challenges and real projects.
"What if we used a single pass with a stack 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 a node counting from the end of the linked list, not from the start.Step 2: Identify the correct action
Deleting the Nth node from the end means locating it and removing it from the list.Final Answer:
Delete the node that is the Nth from the end in a linked list -> Option DQuick Check:
Remove Nth node from end = Delete node Nth from end [OK]
- Confusing Nth from start with Nth from end
- Thinking the problem is about reversing the list
- Trying to add nodes instead of removing
head?Solution
Step 1: Understand dummy node creation
A dummy node is usually created with a value (often 0) and its next pointer set to the head.Step 2: Check each option
dummy = ListNode(0); dummy.next = head correctly creates a dummy node with value 0 and points its next to head.Final Answer:
dummy = ListNode(0); dummy.next = head -> Option CQuick Check:
Dummy node points to head = dummy.next = head [OK]
- Passing head as value instead of next pointer
- Overwriting dummy after creation
- Not linking dummy to head
1 -> 2 -> 3 -> 4 -> 5 -> null?Solution
Step 1: Identify the 2nd node from the end
Counting from the end: 5 (1st), 4 (2nd). So node with value 4 is to be removed.Step 2: Remove node 4 and link previous node to next
Node 3's next pointer should now point to node 5, skipping node 4.Final Answer:
1 -> 2 -> 3 -> 5 -> null -> Option AQuick Check:
Remove 2nd from end (4) = 1->2->3->5 [OK]
- Removing the wrong node counting from start
- Not updating the previous node's next pointer
- Confusing node values
def removeNthFromEnd(head, n):
dummy = ListNode(0)
dummy.next = head
first = dummy
second = dummy
for i in range(n):
first = first.next
while first.next:
first = first.next
second = second.next
second.next = second.next.next
return dummy.nextSolution
Step 1: Analyze the for loop moving first pointer
To position first pointer n nodes ahead, it must move n+1 times to maintain gap with second pointer.Step 2: Understand the impact of moving first pointer only n times
If first moves only n times, the gap is off by one, causing wrong node removal.Final Answer:
The for loop should run n+1 times to move first pointer -> Option AQuick Check:
Move first pointer n+1 times for correct gap [OK]
- Moving first pointer only n times
- Incorrect while loop condition
- Ignoring dummy node usage
1 -> 2 -> 3 -> 4 -> 5 -> null. If you remove the 5th node from the end, what will be the resulting list?Solution
Step 1: Identify the 5th node from the end
The list length is 5, so the 5th node from the end is the first node with value 1.Step 2: Remove the first node and link dummy to second node
Removing node 1 means the new head is node 2, so list becomes 2 -> 3 -> 4 -> 5 -> null.Final Answer:
2 -> 3 -> 4 -> 5 -> null -> Option BQuick Check:
Remove 5th from end (head) = 2->3->4->5 [OK]
- Removing last node instead of first
- Not updating head pointer after removal
- Confusing node positions
Ready to prove it?
Pass the test and this pattern moves unknown
