模擬周賽281。又是奇怪的一題,2N的解法竟然比N還快。

題目

輸入一個linked list的首節點,其中包含好幾個由0分隔開的整數,且此list的頭尾節點值都是0。
將位於兩個0之間的節點值加總,合併為一個節點。合併完的list不應該存在任何0。
回傳合併完的list。

解法

題目已經講明了頭尾一定是0,且最少出現3個節點以上,而且不會有兩個0相鄰,這樣就不用處理任何例外。
輸入的list一定長成這樣的結構:

0..0..0

我們可以忽略掉第一個0,處理的邏輯就會從合併兩個0之間的節點簡化成加總節點值,碰到0後結算
維護變數sm,代表連續節點的加總值,指針curr從第二個節點開始向後遍歷:當curr不為0時,加總;否則建立一個值為sm的新節點,暫存在nodes中。
遍歷完後nodes中會有數個合併完的節點,再遍歷一次nodes將其串接後回傳即可。

class Solution:
    def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
        nodes=[]
        curr=head.next
        sm=0
        while curr:
            if curr.val==0:
                nodes.append(ListNode(sm))
                sm=0
            else:
                sm+=curr.val
            curr=curr.next
            
        for i in range(len(nodes)-1):
            nodes[i].next=nodes[i+1]
            
        return nodes[0]

也可以在合併時直接建立新節點並串接,遍歷次數降低到1次。
利用偽首節點dummy儲存新建的節點,加上tail變數指向新節點的最尾端,每次碰到0節點時建立一個值為sm的新節點,附加到tail後方,再將tail後移一步。
最後dummy.next就是新list的首節點。

class Solution:
    def mergeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy=tail=ListNode()
        curr=head.next
        sm=0
        
        while curr:
            if curr.val==0:
                tail.next=ListNode(sm)
                tail=tail.next
                sm=0
            else:
                sm+=curr.val
            curr=curr.next
            
        return dummy.next