You are given the head
of a linked list and two integers m
and n
.
Traverse the linked list and remove some nodes in the following way:
m
nodes starting at the current node.n
nodes, starting at the m + 1
node.Return the head of the modified list.
Example 1:
Input: head = [1,2,3,4,5,6,7,8,9,10,11,12,13], m = 2, n = 3 Output: [1,2,6,7,11,12] Explanation: Keep the first 2 nodes, delete the next 3 nodes. Repeat until the end of the list.
Example 2:
Input: head = [1,2,3,4,5,6,7,8,9,10,11], m = 1, n = 3 Output: [1,5,9] Explanation: Keep the first 1 node, delete the next 3 nodes. Repeat until the end of the list.
Example 3:
Input: head = [1,2,3,4,5,6,7,8,9,10,11], m = 3, n = 1 Output: [1,2,3,5,6,7,9,10,11]
Constraints:
[1, 104]
.1 <= m, n <= 1000
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:
The brute force method to solve this list manipulation challenge involves going through the list, keeping some items and removing others, based on the given numbers. We'll walk through the list and perform deletions according to the rules.
Here's how the algorithm would work step-by-step:
def delete_n_nodes_after_m_nodes(head, m_value, n_value): current_node = head
while current_node:
# Keep m nodes
for _ in range(m_value - 1):
if current_node is None:
return head
current_node = current_node.next
# If we reached the end of the list
if current_node is None:
return head
next_node = current_node.next
# Delete n nodes
for _ in range(n_value):
if next_node is None:
break
next_node = next_node.next
# Connect the m nodes to the node after the n deleted nodes
# This effectively removes the n nodes
current_node.next = next_node
# Advance current_node to the new next node to continue the process
current_node = next_node
return head
The efficient way to solve this linked list problem is to walk through the list and strategically skip nodes. We'll use two counters to keep track of which nodes to keep and which to skip.
Here's how the algorithm would work step-by-step:
class ListNode:
def __init__(self, value=0, next_node=None):
self.value = value
self.next = next_node
def delete_n_nodes_after_m_nodes(head, number_of_nodes_to_keep, number_of_nodes_to_delete):
current_node = head
while current_node:
# Traverse M nodes
for _ in range(number_of_nodes_to_keep - 1):
if current_node is None:
return head
current_node = current_node.next
# If we reach the end, no more nodes to delete
if current_node is None:
return head
next_node = current_node.next
# Delete N nodes
for _ in range(number_of_nodes_to_delete):
if next_node is None:
break
next_node = next_node.next
# Link the kept nodes to the node after the deleted nodes
current_node.next = next_node
current_node = next_node
return head
Case | How to Handle |
---|---|
head is null | Return null immediately as there is no list to process. |
m is 0 | Delete every node from head to tail and return null. |
n is 0 | Return the original head because we keep all nodes. |
m is larger than the length of the list | Keep the entire list since there aren't enough nodes to delete after m nodes; simply return the original head. |
n is larger than the remaining list length after m nodes | Delete all remaining nodes after retaining m nodes. |
m and n are large, leading to potential integer overflow if summed repeatedly | The loop condition should only depend on list traversal, avoiding calculations with potentially overflowing values. |
List length is very large, potentially impacting performance | The iterative approach is used to ensure linear time complexity O(N) and avoid stack overflow issues from recursion with long lists. |
Both m and n are extremely large and close to the maximum integer value | The code will still execute correctly as long as individual m and n calculations stay within valid integer ranges during traversal, it does not matter that their sum is invalid. |