🔗 🟡 2181. Merge Nodes in Between Zeros 1333

tags: Weekly Contest 281 鏈結串列(Linked List) 模擬(Simulation)

題意

給定一個 鏈結串列(Linked List) 的第一個節點 headhead,其中包含一系列以 00 分隔的整數,且鏈結串列的開頭和結尾都滿足 node.val==0node.val == 0

對於相鄰的每兩個 00,將它們之間的所有節點合併為一個節點,其值為所有已合併節點的和。然後將所有 00 移除,修改後的鏈結串列不應包含任何 00

返回修改後的鏈結串列的頭節點 headhead

思路:模擬(Simulation)

根據題意,若 Linked List 中有 m+1m + 1 個節點為 00 ,則需返回包含 mm 個節點的新 Linked List。

我們可以先將所有 00 節點保留,並在計算完中間節點的和後,將其保存到 後面 的那個 00 節點中,然後將前面的 00 節點連接到後面的 00 節點,最後去除第一個 00 節點即可。

具體步驟如下:

  1. 初始化兩個指標 preprecurcurprepre 用於指向上一次出現值為 00 的節點,curcur 用於遍歷鏈結串列。
    • 由於題目確保第一個節點的值為 00,因此初始化 pre=headpre = head
    • curcur 指向 headhead 的下一個節點 head.nexthead.next
  2. 使用一個變數 ss 來累加兩個 00 節點之間的節點值,初始化 s=0s = 0
  3. 遍歷鏈結串列,對於每個節點:
    • 如果節點值為 00,表示找到了一段需要合併的區間。此時:
      • 將當前節點的值設置為 ss,並將 ss 重置為 00
      • pre.nextpre.next 指向當前節點,以便移除中間的所有節點。
      • prepre 更新為當前節點。
    • 如果節點值不為 00,則累加 ss
  4. 最後返回修改後的鏈結串列的頭節點。注意,初始的第一個 00 節點不需要,所以返回 head.nexthead.next

複雜度分析

  • 時間複雜度:O(n)\mathcal{O}(n)nn 為鏈結串列的節點數量。
  • 空間複雜度:O(1)\mathcal{O}(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution:
def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head is None: # for pylance
return None
pre = head # previous 0 node
cur = head.next
s = 0
while cur:
if cur.val == 0:
cur.val = s
s = 0
pre.next = cur # connect the previous 0 node to the current node
pre = cur
else:
s += cur.val
cur = cur.next
return head.next # the first 0 node is not needed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
ListNode* mergeNodes(ListNode* head) {
ListNode *pre = head, *cur = head->next;
int s = 0;
while (cur != nullptr) {
if (cur->val == 0) {
cur->val = s;
s = 0;
pre->next = cur;
pre = cur;
} else {
s += cur->val;
}
cur = cur->next;
}
return head->next;
}
};

寫在最後

Cover photo is remixed from @吃肥皂泡泡, thanks for their work!