Pop Using Linked List Node in DSA Python - Time & Space Complexity
We want to understand how long it takes to remove the last item from a linked list.
How does the time needed change as the list gets bigger?
Analyze the time complexity of the following code snippet.
class Node:
def __init__(self, value):
self.value = value
self.next = None
def pop(head):
if head is None:
return None
if head.next is None:
return None # List becomes empty after pop
current = head
while current.next.next is not None:
current = current.next
current.next = None
return head
This code removes the last node from a singly linked list by walking through the list to find the second last node.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves through nodes to find the second last node.
- How many times: It runs once for each node until the second last one, so about n-2 times for a list of size n.
As the list gets longer, the loop runs more times, almost once per node.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 8 steps |
| 100 | About 98 steps |
| 1000 | About 998 steps |
Pattern observation: The number of steps grows roughly in a straight line with the size of the list.
Time Complexity: O(n)
This means the time to pop the last node grows directly with the number of nodes in the list.
[X] Wrong: "Popping the last node is always quick and takes constant time."
[OK] Correct: Because we must find the second last node by walking through the list, which takes longer as the list grows.
Understanding this helps you explain why some linked list operations are slower than others and shows you can analyze code carefully.
"What if the linked list kept a pointer to the last node? How would the time complexity of pop change?"
Practice
pop operation do in a linked list when using nodes?Solution
Step 1: Understand pop operation in linked list
Pop means removing the last element from the list and returning its value.Step 2: Identify pop behavior with nodes
In a linked list, pop removes the tail node and returns its data.Final Answer:
Removes the last node and returns its value -> Option AQuick Check:
Pop = Remove last node [OK]
- Confusing pop with push (adding nodes)
- Thinking pop removes the first node
- Assuming pop searches for a value
Solution
Step 1: Check pop logic for singly linked list
Pop removes the last node, so we must traverse to the second last node.Step 2: Verify syntax correctness
def pop(self):\n if not self.head:\n return None\n current = self.head\n while current.next.next:\n current = current.next\n popped = current.next\n current.next = None\n return popped.data correctly traverses until current.next.next is None, then removes last node and returns its data.Final Answer:
Code that traverses to second last node -> Option AQuick Check:
Traverse to second last node, remove last [OK]
- Removing head instead of last node
- Not checking for empty list
- Returning node instead of node data
1 -> 2 -> 3 -> null using the pop method below?def pop(self):
if not self.head:
return None
if not self.head.next:
val = self.head.data
self.head = None
return val
current = self.head
while current.next.next:
current = current.next
val = current.next.data
current.next = None
return valSolution
Step 1: Identify the node popped
Pop removes the last node, which is 3 in the list 1 -> 2 -> 3 -> null.Step 2: Determine list after pop
After removing 3, the list becomes 1 -> 2 -> null.Final Answer:
1 -> 2 -> null -> Option CQuick Check:
Last node removed, list ends at 2 [OK]
- Removing first node instead of last
- Not updating next pointer to None
- Returning wrong list after pop
def pop(self):
current = self.head
while current.next:
current = current.next
val = current.data
current = None
return valSolution
Step 1: Analyze traversal and removal
The code moves current to last node but does not track previous node.Step 2: Check pointer update
Setting current = None only changes local variable, does not update previous node's next pointer to None, so last node remains linked.Final Answer:
It does not update the previous node's next pointer -> Option BQuick Check:
Must update previous.next to None to remove last node [OK]
- Not handling empty list
- Not tracking previous node
- Setting local variable to None instead of pointer
10 -> 20 -> 30 -> 40 -> null, write the sequence of node values after two consecutive pop operations using a correct pop method that removes the last node each time.Solution
Step 1: First pop removes last node 40
List changes from 10 -> 20 -> 30 -> 40 -> null to 10 -> 20 -> 30 -> null.Step 2: Second pop removes new last node 30
List changes from 10 -> 20 -> 30 -> null to 10 -> 20 -> null.Final Answer:
10 -> 20 -> null -> Option DQuick Check:
Two pops remove last two nodes [OK]
- Removing nodes from start instead of end
- Not updating list after first pop
- Confusing node values after pops
Ready to prove it?
Pass the test and this pattern moves unknown
