合並兩個有序鏈表(遞歸和迭代)


合並兩個有序鏈表

概述:

  將兩個有序鏈表合並為一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 示例:輸入:1->2->4, 1->3->4 輸出:1->1->2->3->4->4

方法一:遞歸

遞歸地定義在兩個鏈表里的 merge 操作:

  list1[0]+merge(list1[1:],list2) list1[0]<list2[0]

  list2[0]+merge(list1,list2[1:])​ otherwise​

遞歸過程:判斷 l1l2 哪一個的頭元素更小,然后遞歸地決定下一個添加到結果里的值。如果兩個鏈表都是空的,那么過程終止,所以遞歸過程最終一定會終止。

class Solution:
    def mergeTwoLists(self, l1, l2):
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2
  • 時間復雜度:O(n+m) 。 因為每次調用遞歸都會去掉 l1 或者 l2 的頭元素(直到至少有一個鏈表為空),函數 mergeTwoList 中只會遍歷每個元素一次。所以,時間復雜度與合並后的鏈表長度為線性關系。
  • 空間復雜度:O(n+m) 。調用 mergeTwoLists 退出時 l1 和 l2 中每個元素都一定已經被遍歷過了,所以 n+m 個棧幀會消耗 O(n+m) 的空間。

方法二:迭代

class Solution:
    def mergeTwoLists(self, l1, l2):
        # maintain an unchanging reference to node ahead of the return node.
        prehead = ListNode(-1)

        prev = prehead
        while l1 and l2:
            if l1.val <= l2.val:
                prev.next = l1
                l1 = l1.next
            else:
                prev.next = l2
                l2 = l2.next            
            prev = prev.next

        # exactly one of l1 and l2 can be non-null at this point, so connect
        # the non-null list to the end of the merged list.
        prev.next = l1 if l1 is not None else l2

        return prehead.next
  • 時間復雜度:O(n+m) 。因為每次循環迭代中,l1 和 l2 只有一個元素會被放進合並鏈表中, while 循環的次數等於兩個鏈表的總長度。所有其他工作都是常數級別的,所以總的時間復雜度是線性的。
  • 空間復雜度:O(1) 。迭代的過程只會產生幾個指針,所以它所需要的空間是常數級別的。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM