Medium

题目描述

给你一个链表的头节点 head ,该链表包含由 0 分隔开的一连串整数。链表的开头和结尾的节点都满足 Node.val == 0

对于每两个相邻的 0 ,请你将它们之间的所有节点合并成一个节点,其值是所有合并节点的值的总和。修改后的链表不应该含有任何 0

返回修改后链表的头节点。

示例 1:

输入:head = [0,3,1,0,4,5,2,0]
输出:[4,11]
解释:
上图表示输入的链表。修改后的链表包含:
- 标记为绿色的节点之和:3 + 1 = 4
- 标记为红色的节点之和:4 + 5 + 2 = 11

示例 2:

输入:head = [0,1,0,3,0,2,2,0]
输出:[1,3,4]
解释:
上图表示输入的链表。修改后的链表包含:
- 标记为绿色的节点之和:1 = 1
- 标记为红色的节点之和:3 = 3  
- 标记为黄色的节点之和:2 + 2 = 4

提示:

  • 链表中的节点数目在范围 [3, 2 * 10^5]
  • 0 <= Node.val <= 1000
  • 不存在连续两个 Node.val == 0 的节点
  • 链表的开头和结尾节点都满足 Node.val == 0

解题思路

解题思路

这道题要求我们将链表中两个0之间的所有节点合并为一个节点,节点值为区间内所有节点值的和。

核心思路

  1. 双指针法:使用两个指针,一个用于遍历原链表,另一个用于构建新链表
  2. 区间求和:遍历每个0之间的区间,累加节点值
  3. 原地修改:直接修改原链表结构,节省空间

算法步骤

  1. 跳过第一个0节点,从第二个节点开始遍历
  2. 使用一个指针遍历链表,另一个指针指向当前要修改的节点
  3. 当遇到非0节点时,累加其值到当前区间和
  4. 当遇到0节点时,将累积的和赋值给修改指针指向的节点,然后移动修改指针
  5. 最后将修改指针的next设为null,完成链表构建

这种方法的优势是直接在原链表上修改,无需额外创建新节点,既简洁又高效。时间复杂度为O(n),空间复杂度为O(1)。

代码实现

class Solution {
public:
    ListNode* mergeNodes(ListNode* head) {
        ListNode* modify = head->next;
        ListNode* curr = modify;
        
        while (curr) {
            int sum = 0;
            while (curr && curr->val != 0) {
                sum += curr->val;
                curr = curr->next;
            }
            
            modify->val = sum;
            curr = curr->next;
            modify->next = curr;
            modify = curr;
        }
        
        return head->next;
    }
};
class Solution:
    def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
        modify = head.next
        curr = modify
        
        while curr:
            sum_val = 0
            while curr and curr.val != 0:
                sum_val += curr.val
                curr = curr.next
            
            modify.val = sum_val
            curr = curr.next
            modify.next = curr
            modify = curr
        
        return head.next
public class Solution {
    public ListNode MergeNodes(ListNode head) {
        ListNode modify = head.next;
        ListNode curr = modify;
        
        while (curr != null) {
            int sum = 0;
            while (curr != null && curr.val != 0) {
                sum += curr.val;
                curr = curr.next;
            }
            
            modify.val = sum;
            curr = curr.next;
            modify.next = curr;
            modify = curr;
        }
        
        return head.next;
    }
}
var mergeNodes = function(head) {
    let modify = head.next;
    let curr = modify;
    
    while (curr) {
        let sum = 0;
        while (curr && curr.val !== 0) {
            sum += curr.val;
            curr = curr.next;
        }
        
        modify.val = sum;
        curr = curr.next;
        modify.next = curr;
        modify = curr;
    }
    
    return head.next;
};

复杂度分析

复杂度分析
时间复杂度O(n),其中 n 是链表中节点的数量,需要遍历每个节点一次
空间复杂度O(1),只使用了常数个额外变量,原地修改链表结构

相关题目