This problem involves traversing a linked list and deleting nodes based on a pattern: keep m
nodes, then delete n
nodes, repeating this process until the end of the list. The solution uses an iterative approach with two pointers to efficiently manage the deletion.
Initialization: Two pointers, pre
and cur
, are used. pre
tracks the node before the group of n
nodes to be deleted, and cur
iterates through the n
nodes to be deleted. Both start at the head of the list.
Keep m
nodes: The outer while
loop iterates until pre
reaches the end of the list. Inside, a for
loop advances pre
m-1
times, positioning it correctly before the deletion sequence. If pre
becomes null
before completing m-1
steps, it means there are fewer than m
nodes remaining, so the loop ends, and the modified list is returned.
Delete n
nodes: Another for
loop advances cur
n
times, traversing the nodes to be deleted. If cur
becomes null
before completing n
steps, it means fewer than n
nodes are left after the m
nodes, so the loop ends.
Update Links: The crucial step is updating the links to remove the n
nodes. pre.next
is set to cur.next
, effectively bypassing the n
nodes. The cur == null ? null : cur.next
part handles the edge case where fewer than n
nodes remain.
Advance pre
: Finally, pre
is advanced to pre.next
to begin the next iteration of the process.
Return Head: After the while
loop completes, the head of the modified linked list is returned.
pre
and cur
, regardless of the list's size.Python:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode:
pre = head # Pointer before deletion sequence
while pre: # Iterate until the end of the list
for _ in range(m - 1): # Move pre m-1 steps
if pre:
pre = pre.next
else:
return head #Handle edge case of less than m nodes
if pre is None: # Check if pre reached the end before completing m-1 steps
return head
cur = pre # Pointer for the nodes to be deleted
for _ in range(n): #Move cur n steps
if cur:
cur = cur.next
else:
break # Handle edge case of less than n nodes after m nodes
pre.next = cur #Update the link to bypass the deleted nodes.
pre = pre.next # Move pre to the next group of m nodes
return head
The other languages (Java, C++, Go, TypeScript) follow a very similar structure, adapting the syntax and data structures as needed. The core logic of using two pointers to manage the deletion remains consistent across all implementations.