合並兩個有序鏈表
概述:
將兩個有序鏈表合並為一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 示例:輸入: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
遞歸過程:判斷 l1
和 l2
哪一個的頭元素更小,然后遞歸地決定下一個添加到結果里的值。如果兩個鏈表都是空的,那么過程終止,所以遞歸過程最終一定會終止。
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) 。迭代的過程只會產生幾個指針,所以它所需要的空間是常數級別的。