Remove Linked List Elements Solution for Capgemini
Company: Capgemini · Difficulty: Easy · Topics: Linked List, Recursion
Problem Statement
Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.
The linked list is defined as:
- Each node contains a value and a reference to the next node
- The head is the first node of the linked list
Examples
Example 1:
Input: head = [1,2,6,3,4,5,6], val = 6
Output: [1,2,3,4,5]
Explanation: Remove all nodes with value 6.
Example 2:
Input: head = [], val = 1
Output: []
Explanation: Empty list remains empty.
Example 3:
Input: head = [7,7,7,7], val = 7
Output: []
Explanation: Remove all nodes with value 7.
Intuition
We need to traverse the linked list and remove all nodes that have the target value. We can use a dummy node to handle the case where the head node needs to be removed.
Approach
Approach 1: Dummy Node (Optimal)
1. Create a dummy node pointing to head
2. Use a pointer to traverse the list
3. When current node's next has target value, skip it
4. Return dummy.next as new head
Approach 2: Recursion
1. Base case: if head is null, return null
2. If head.val == val, return removeElements(head.next, val)
3. Otherwise, head.next = removeElements(head.next, val)
4. Return head
Approach 3: Iterative without Dummy
1. Handle head removal separately
2. Use two pointers: prev and current
3. When current.val == val, update prev.next
4. Update pointers accordingly
Dry Run
Let's trace through Example 1: head = [1,2,6,3,4,5,6], val = 6
Dummy Node Approach:
- Create dummy → [1,2,6,3,4,5,6]
- curr = dummy
- curr.next = 1, 1 != 6 → move curr
- curr.next = 2, 2 != 6 → move curr
- curr.next = 6, 6 == 6 → curr.next = curr.next.next
- curr.next = 3, 3 != 6 → move curr
- curr.next = 4, 4 != 6 → move curr
- curr.next = 5, 5 != 6 → move curr
- curr.next = 6, 6 == 6 → curr.next = curr.next.next
- curr.next = null
- Return dummy.next = [1,2,3,4,5]
Key Insights
1. Dummy Node: Simplifies handling head removal
2. Two Pointers: Use prev and curr for efficient removal
3. Memory Management: Update pointers to avoid memory leaks
4. Edge Cases: Handle empty list and all nodes being removed
Edge Cases
1. Empty list: Return null
2. Head removal: First node has target value
3. All nodes removed: Return empty list
4. Consecutive removals: Multiple target values in a row
5. Last node removal: Target value at end
Time and Space Complexity
- Time Complexity: O(n) - Single pass through list
- Space Complexity: O(1) - Only constant extra space used