每日leetcode——21. 合併兩個有序連結串列

Ethan發表於2022-03-03

題目

將兩個升序連結串列合併為一個新的 升序 連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。

輸入:l1 = [1,2,4], l2 = [1,3,4]
輸出:[1,1,2,3,4,4]

輸入:l1 = [], l2 = []
輸出:[]

輸入:l1 = [], l2 = [0]
輸出:[0]

遞迴

# class ListNode:
#    def __init__(self, val=0, next=None):
#        self.val = val
#        self.next = next

def mergeTwoLists(list1: ListNode, list2: ListNode) -> ListNode:
    if list1 is None:
        return list2
    if list2 is None:
        return list1
    if list1.val < list2.val:
        list1.next = mergeTwoLists(list1.next, list2)
        return list1
    else:
        list2.next = mergeTwoLists(list1, list2.next)
        return list2

時間複雜度:O(n+m),其中 n 和 m 分別為兩個連結串列的長度。因為每次呼叫遞迴都會去掉 l1 或者 l2 的頭節點(直到至少有一個連結串列為空),函式 mergeTwoList 至多隻會遞迴呼叫每個節點一次。因此,時間複雜度取決於合併後的連結串列長度,即 O(n+m)。

空間複雜度:O(n+m),其中 n 和 m 分別為兩個連結串列的長度。遞迴呼叫 mergeTwoLists 函式時需要消耗棧空間,棧空間的大小取決於遞迴呼叫的深度。結束遞迴呼叫時 mergeTwoLists 函式最多呼叫 n+m 次,因此空間複雜度為 O(n+m)。

迭代

1、設定虛擬節點preHead,儲存合併後的連結串列
2、從l1和l2頭節點值開始進行比較,值小那條連結串列的頭結點後移,直至有一條連結串列的頭節點指向為空
3、將剩餘的那條連結串列接上

def mergeTwoLists(list1: ListNode, list2: ListNode) -> ListNode:
    preHead = ListNode(-1)
    prev = preHead

    while list1 and list2:
        if list1.val <= list2.val:
            prev.next = list1
            list1 = list1.next
        else:
            prev.next = list2
            list2 = list2.next
        prev = prev.next

    prev.next = list1 if list1 is not None else list2

    return preHead.next

合併兩個有序連結串列的簡單迭代實現,有點抽象難以理解,可以對照合併兩個有序陣列的簡單迭代實現,要容易理解的多。

相關文章