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之间的所有节点合并为一个节点,节点值为区间内所有节点值的和。
核心思路
- 双指针法:使用两个指针,一个用于遍历原链表,另一个用于构建新链表
- 区间求和:遍历每个0之间的区间,累加节点值
- 原地修改:直接修改原链表结构,节省空间
算法步骤
- 跳过第一个0节点,从第二个节点开始遍历
- 使用一个指针遍历链表,另一个指针指向当前要修改的节点
- 当遇到非0节点时,累加其值到当前区间和
- 当遇到0节点时,将累积的和赋值给修改指针指向的节点,然后移动修改指针
- 最后将修改指针的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),只使用了常数个额外变量,原地修改链表结构 |
相关题目
- . Linked List Components (Medium)