
Problem Statement
In this problem, you are provided with the head of a singly linked list and two integers, m
and n
. Your task is to modify the linked list in such a way that, starting from the head, you retain the first m
nodes and then delete the next n
nodes. This process of keeping m
nodes followed by removing n
nodes continues repeatedly through the list until no more nodes can be processed. The output should be the head of the linked list after all modifications are performed according to the specified pattern of retention and deletion.
Examples
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 (m = 2) nodes starting from the head of the linked List (1 ->2) show in black nodes. Delete the next (n = 3) nodes (3 -> 4 -> 5) show in read nodes. Continue with the same procedure until reaching the tail of the Linked List. Head of the linked list after removing nodes is returned.
Example 2
Input:
head = [1,2,3,4,5,6,7,8,9,10,11], m = 1, n = 3
Output:
[1,5,9]
Explanation:
Head of linked list after removing nodes is returned.
Constraints
- The number of nodes in the list is in the range
[1, 104]
. 1 <= Node.val <= 106
1 <= m, n <= 1000
Approach and Intuition
When approaching this problem, the key is to handle the linked list traversal and modification efficiently while keeping track of the nodes. Here’s the step-by-step approach:
- Initialize a pointer, say
current
, to point to the head of the linked list. - Traverse the
m
nodes starting from thecurrent
node. This is to ensure thesem
nodes are retained.- For each of the
m
nodes, check if thecurrent
pointer is null which indicates the end of the list. If not, simply move thecurrent
pointer to the next node.
- For each of the
- Once
m
nodes are retained, move to deleting the nextn
nodes. This necessitates careful manipulation of the list pointers.- Keep another pointer, let’s call it
prev
, which should always point to the last node that is not deleted (last ofm
retained nodes). - Now increment the
current
pointer through the nextn
nodes. For each node, ensure you adjust the link fromprev
to skip the node currently pointed to bycurrent
.
- Keep another pointer, let’s call it
- Continue the above two steps until you have traversed the entire list or until the
current
pointer is null. - Return the modified linked list starting from the head.
The intuition here is to effectively manage the pointers as you traverse the list so that you can skip over the n
nodes without losing the reference to the part of the list you need to retain. Also, it’s crucial to maintain an efficient approach to not revisit nodes unnecessarily which would otherwise increase the time complexity.
Solutions
- C++
- Java
class Solution {
public:
ListNode* removeNodes(ListNode* head, int m, int n) {
ListNode* current = head;
ListNode* previousMNode = head;
while (current != nullptr) {
int keepCount = m, deleteCount = n;
while (current != nullptr && keepCount != 0) {
previousMNode = current;
current = current->next;
keepCount--;
}
while (current != nullptr && deleteCount != 0) {
current = current->next;
deleteCount--;
}
previousMNode->next = current;
}
return head;
}
};
This solution implements functionality to modify a linked list by preserving 'm' nodes followed by deleting 'n' nodes repeatedly through the list. The function removeNodes
accepts a head pointer to the linked list, and two integers, m
and n
, indicating the numbers of nodes to keep and delete respectively.
Here’s a breakdown of the implementation:
- Initialize
current
to point to the head of the list, which helps traverse the list.previousMNode
is also pointed to the head to assist in linking nodes after deletions. - Use a
while
loop that continues untilcurrent
reaches the end of the list (nullptr
). - Inside the primary loop, two nested
while
loops manage the skipping and deletion of nodes:- The first
while
loop iterates over 'm' nodes (or until the end of the list), movingcurrent
and settingpreviousMNode
tocurrent
after each iteration. - The second
while
loop skips 'n' nodes following the m nodes that are kept.current
is moved forward 'n' places.
- The first
- After the iterations, link
previousMNode->next
tocurrent
to effectively skip(delete) the 'n' nodes. - Finally, the function returns the head of the modified linked list.
This method changes the linked list in-place with a time complexity of O(m+n) per repetitive sequence until the end and uses O(1) additional space since it modifies the list by rearranging pointers.
class Solution {
public ListNode removeNAfterM(ListNode start, int m, int n) {
ListNode current = start;
ListNode lastPreserved = start;
while (current != null) {
int mCounter = m, nCounter = n;
// Skip m nodes
while (current != null && mCounter != 0) {
lastPreserved = current;
current = current.next;
mCounter--;
}
// Skip n nodes
while (current != null && nCounter != 0) {
current = current.next;
nCounter--;
}
// Connect m-th node to the node after n skipped nodes
lastPreserved.next = current;
}
return start;
}
}
The given Java code defines a method that modifies a linked list by skipping n
nodes after every m
nodes. This adjustment is achieved through the following sequence:
- Initiate
current
to point to the start of the linked list to traverse through the nodes. - Maintain a reference
lastPreserved
that will help link the nodes that are being kept in the list. - Use a while loop to iterate through the linked list until
current
becomesnull
, meaning the end of the list has been reached. - Employ an inner while loop to bypass
m
nodes. It decrements themCounter
each time until it reaches zero, effectively movingcurrent
forward bym
nodes while adjustinglastPreserved
to the final node in this segment. - Utilize another inner while loop for skipping a consecutive sequence of
n
nodes. It decrements thenCounter
each iteration, movingcurrent
forward to bypass the nodes meant for deletion. - Link the
lastPreserved
node to the node immediately following then
nodes that were skipped by updatinglastPreserved.next
tocurrent
.
After completing the iterations, the function returns the modified start
node of the linked list, effectively reflecting the newly reordered liste without the removed nodes. This method accomplishes node adjustments in a single pass, making it efficient in terms of time and space complexity.
No comments yet.