0021. Merge Two Sorted Lists - chasel2361/leetcode GitHub Wiki
Merge two sorted linked lists and return it as a new list.
The new list should be made by splicing together the nodes of the first two lists.
Example:
Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4
在解這題之前必須先理解什麼是 singly-linked list (單向連結串列),singly-linked list 是由許多個 ListNode 所形成,其定義如下:
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
而單向連接串列的定義大概可以像下面這樣,輸入一個 list,輸出一個單項連結的節點
def GenSinglyLinkedList(nums: list):
nodes = [ListNode(n) for n in nums]
for i in range(len(nodes) - 1):
nodes[i].next = nodes[i+1]
return nodes[0]
所以只要找到串列的頭,就可以(也只能)依序一個一個節點往下找到所有節點,所以上面的範例可以表示為
# input
l1 = GenListNode([1, 2, 4])
l2 = GenListNode([1, 3, 4])
#output
l3 = GenListNode([1, 1, 2, 3, 4, 4])
因此,我們可以利用一個 dummy head (下稱 dummy ) 來指向第一個內容為 None 的暫時節點 cur,由於 dummy 僅單向指向 cur,cur 與其他節點串接不影響 dummy。
迭代法 (iteratively)
[1] 創造一個空的 dummy 將其指標指向游標解點 cur
[2] 依序比較 l1 及 l2 的值,將 cur.next 指向 val 較小的串列,並將 l1 或 l2 指向下一個節點
[3] 將 cur 指下一個節點 cur.next ,準備判斷下一個節點,此時 dummy 仍然指向原本的第一個節點
[4] 當 l1 或 l2 其中一個不存在之後,就不需要判斷了,直接把 cur.next 指向剩下的那一個串列
[5] 由於 dummy 指向 cur ,其 var 值不是我們需要的,所以回傳 dummy.next 即可
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1 or not l2:
return l2 or l1
dummy = cur = ListNode(None) # [1]
while l1 and l2:
if l1.val < l2.val:
cur.next = l1
l1 = l1.next # [2]
else:
cur = l2
l2.next = l2.next # [2]
cur = cur.next # [3]
cur.next = l1 or l2 # [4]
return dummy.next # [5]
迭代法的時間及空間複雜度皆為O(N)
遞迴法 (recursively)
遞迴法的概念在於重複呼叫自身函式,在程式撰寫上較為簡潔,但時間與空間複雜度也較高,可以看這份文件 Python 初學第八講 — 遞迴 - ccClub
[1] 若 l1.val < l2.val ,重新呼叫本身函數,輸入 l1.next 及 l2 ,將 l1.next 指向其回傳值,會不停遞迴直至其中一個物件指向 None 為止
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if not l1 or not l2:
return l2 or l1
if l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2) # [1]
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next) # [1]
return l2
遞迴法的時間以及空間複雜度亦為O(N)