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.
Example 1:
Input: head = [1,2,6,3,4,5,6], val = 6 Output: [1,2,3,4,5]
Example 2:
Input: head = [], val = 1 Output: []
Example 3:
Input: head = [7,7,7,7], val = 7 Output: []
Constraints:
[0, 104]
.1 <= Node.val <= 50
0 <= val <= 50
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine you have a chain of connected items, and you want to remove specific unwanted items from this chain. The brute force method involves going through the chain and, for each item, checking if it needs to be removed. If it does, we take it out.
Here's how the algorithm would work step-by-step:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def remove_linked_list_elements_brute_force(head, value):
current_node = head
previous_node = None
while current_node:
# Check if the current node's value matches the value to remove
if current_node.val == value:
if previous_node:
# Bypass the current node to remove it
previous_node.next = current_node.next
else:
# If the head node needs to be removed, update the head
head = current_node.next
current_node = current_node.next
else:
# Move both pointers forward
previous_node = current_node
current_node = current_node.next
return head
The trick to efficiently removing elements from a linked list is to carefully step through the list and make adjustments as you go. We'll use a 'helper' to keep track of where we are and make changes safely, especially at the beginning of the list. This helps us avoid accidentally losing parts of the list.
Here's how the algorithm would work step-by-step:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def removeElements(head: ListNode, value: int) -> ListNode:
dummy_node = ListNode(0)
dummy_node.next = head
current_node = head
previous_node = dummy_node
# Use a helper to handle the head removal case elegantly.
while current_node:
if current_node.val == value:
# Remove the node by updating the previous node's next pointer.
previous_node.next = current_node.next
current_node = current_node.next
else:
# Advance both pointers only if no removal is needed.
previous_node = current_node
current_node = current_node.next
# The dummy node's next is now the new head.
return dummy_node.next
Case | How to Handle |
---|---|
Empty linked list (head is null) | Return null immediately as there are no nodes to process. |
Linked list with only one node and its value equals val | Return null since the only node needs to be removed. |
Linked list with only one node and its value is not equal to val | Return the original list (head) as there is nothing to remove. |
All nodes in the linked list have a value equal to val | Return null after removing all nodes. |
The value 'val' appears at the beginning of the linked list | Update the head pointer to the first node whose value is not equal to val. |
The value 'val' appears at the end of the linked list | Properly update the 'next' pointer of the node preceding the last node to null. |
The value 'val' appears multiple times consecutively within the linked list | Traverse and skip all consecutive nodes with the value 'val'. |
Very large linked list to test for performance and memory usage. | Iterative solution is preferred for space complexity; recursion might cause stack overflow. |