Delete Node by Value in DSA Go - Time & Space Complexity
We want to understand how long it takes to remove a node by its value from a linked list.
How does the time needed change as the list gets bigger?
Analyze the time complexity of the following code snippet.
func deleteNode(head *Node, value int) *Node {
if head == nil {
return nil
}
if head.val == value {
return head.next
}
current := head
for current.next != nil {
if current.next.val == value {
current.next = current.next.next
break
}
current = current.next
}
return head
}
This code removes the first node with the given value from a singly linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop through the linked list nodes one by one.
- How many times: Up to n times, where n is the number of nodes in the list.
As the list grows, the time to find and delete the node grows roughly in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 checks |
| 100 | Up to 100 checks |
| 1000 | Up to 1000 checks |
Pattern observation: The number of steps grows directly with the list size.
Time Complexity: O(n)
This means the time to delete a node grows linearly with the number of nodes in the list.
[X] Wrong: "Deleting a node by value always takes the same time, no matter the list size."
[OK] Correct: You must search the list to find the node, so bigger lists usually take more time.
Understanding this helps you explain how linked list operations scale, a key skill in many coding discussions.
"What if the list was doubly linked? How would the time complexity change?"
Practice
Delete Node by Value operation in a linked list?Solution
Step 1: Understand the operation's goal
The operation aims to remove a node that matches a specific value from the linked list.Step 2: Identify the correct description
Removing the first node with the given value matches To remove the first node that contains the given value from the list, while others describe different operations.Final Answer:
To remove the first node that contains the given value from the list -> Option BQuick Check:
Delete node by value means remove matching node [OK]
- Confusing deletion with insertion
- Thinking it finds position instead of deleting
- Assuming it reverses the list
head?Solution
Step 1: Check for empty list and head node value
if head == nil { return head } if head.val == 5 { return head.next } curr := head for curr.next != nil && curr.next.val != 5 { curr = curr.next } if curr.next != nil { curr.next = curr.next.next } return head correctly returns head.next if head's value is 5, handling deletion at the start.Step 2: Traverse and delete node with value 5
if head == nil { return head } if head.val == 5 { return head.next } curr := head for curr.next != nil && curr.next.val != 5 { curr = curr.next } if curr.next != nil { curr.next = curr.next.next } return head uses a loop to find the node before the target and updates links properly; others miss this or incorrectly update pointers.Final Answer:
Option A code correctly deletes the first node with value 5 -> Option AQuick Check:
Proper pointer update and head check = if head == nil { return head } if head.val == 5 { return head.next } curr := head for curr.next != nil && curr.next.val != 5 { curr = curr.next } if curr.next != nil { curr.next = curr.next.next } return head [OK]
- Not handling deletion when head node matches
- Incorrect pointer updates causing list break
- Skipping traversal or deleting wrong node
Solution
Step 1: Identify the first node with value 5
The first 5 appears as the third node in the list (1 -> 3 -> 5).Step 2: Remove that node and link previous to next
Deleting this node links 3 directly to 7, resulting in 1 -> 3 -> 7 -> 5 -> null.Final Answer:
1 -> 3 -> 7 -> 5 -> null -> Option DQuick Check:
First 5 removed, rest unchanged = 1 -> 3 -> 7 -> 5 -> null [OK]
- Deleting all nodes with value 5
- Removing wrong node (second 5)
- Breaking list links incorrectly
func deleteNode(head *Node, val int) *Node {
curr := head
for curr.next != nil {
if curr.next.val == val {
curr.next = curr.next.next
break
}
curr = curr.next
}
return head
}Solution
Step 1: Analyze head node deletion case
The code starts from head and checks curr.next, so if head itself has the value, it is not deleted.Step 2: Confirm no panic cause
The loop condition curr.next != nil prevents nil pointer dereference, so no panic from accessing curr.next.val.Final Answer:
It does not handle deletion if the head node contains the value -> Option AQuick Check:
Head node deletion missing = It does not handle deletion if the head node contains the value [OK]
- Ignoring head node deletion
- Assuming panic from nil pointer without checking
- Not breaking after deletion causing multiple deletes
Solution
Step 1: Understand single pass deletion removes only first matching node
Each call deletes only the first node with value 4 found.Step 2: Count calls needed and final list
First call removes the first 4 (second node), list becomes 2 -> 6 -> 4 -> 8 -> null. Second call removes the next 4 (third node), list becomes 2 -> 6 -> 8 -> null.Final Answer:
Call twice; final list: 2 -> 6 -> 8 -> null -> Option CQuick Check:
Two calls remove both 4s = Call twice; final list: 2 -> 6 -> 8 -> null [OK]
- Assuming one call removes all matching nodes
- Miscounting nodes deleted per call
- Confusing node positions after deletions
Ready to prove it?
Pass the test and this pattern moves unknown
