Problem
Question
You are given the
headof a linked list, which contains a series of integers separated by0’s. The beginning and end of the linked list will haveNode.val == 0. For every two consecutive0’s, merge all the nodes lying in between them into a single node whose value is the sum of all the merged nodes. The modified list should not contain any0’s. Return theheadof the modified linked list.
Example 1:

Input: head = [0,3,1,0,4,5,2,0] Output: [4,11] Explanation: The above figure represents the given linked list. The modified list contains
- The sum of the nodes marked in green: 3 + 1 = 4.
- The sum of the nodes marked in red: 4 + 5 + 2 = 11.
Example 2:

Input: head = [0,1,0,3,0,2,2,0] Output: [1,3,4] Explanation: The above figure represents the given linked list. The modified list contains
- The sum of the nodes marked in green: 1 = 1.
- The sum of the nodes marked in red: 3 = 3.
- The sum of the nodes marked in yellow: 2 + 2 = 4.
Constraints:
- The number of nodes in the list is in the range
[3, 2 * 105]. 0 <= Node.val <= 1000- There are no two consecutive nodes with
Node.val == 0. - The beginning and end of the linked list have
Node.val == 0.
Solutions
1. Single Pass with a new LinkedList
Time Complexity: | Space Complexity:
To solve the problem, we create a new linked list with a dummy head node new_head. We traverse the original linked list in a single pass. For each node in the original list, if its value is not 0, we add its value to temp_sum. When we encounter a node with a value of 0, we create a new node with the value of temp_sum in the output linked list, then reset temp_sum to 0 to start accumulating the sum for the next segment.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val = val
# self.next = next
class Solution:
def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
new_head = ListNode(0)
new_cur = new_head
temp_sum = 0
cur = head.next # Skip the initial 0 node
while cur:
if cur.val == 0:
new_cur.next = ListNode(temp_sum)
new_cur = new_cur.next
temp_sum = 0
else:
temp_sum += cur.val
cur = cur.next
return new_head.next
2. 🏆 Single Pass with in-place Modifications
Time Complexity: | Space Complexity:
We can slightly modify the approach above to achieve O(1)O(1) space complexity. We use a modify pointer to keep track of 0-valued ListNodes, store the sum in their values, and connect them together.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
temp_sum = 0
modify_prev = head
modify = head
cur = head.next # Skip the initial 0 node
while cur:
if cur.val == 0:
modify_prev = modify
modify.val = temp_sum
modify.next = cur
modify = modify.next
temp_sum = 0
else:
temp_sum += cur.val
cur = cur.next
modify_prev.next = None
return head
3. Recursive
Time Complexity: | Space Complexity:
We can also approach the problem recursively by breaking it into fragments, where we find the sum of values between 0-valued nodes. In our design, we can guarantee that the head is either 0 or None. We modify the head’s value to store the sum and recursively process the list from the next 0-valued node.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head:
return None
node = head.next
node_sum = 0
while node and node.val != 0:
node_sum += node.val
node = node.next
head.val = node_sum
head.next = self.mergeNodes(node)
return head.next if head.val == 0 else head