題目描述
解題思路
解法一:暴力法
- 遍歷k個鏈表,將所有節點值保存到列表中
- 將列表排序
- 遍歷排序後的列表,創建一個新的有序鏈表
python代碼
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
self.nodes = []
tmp = head = ListNode(0)
for i in lists:
while i:
self.nodes.append(i.val)
i = i.next
for j in sorted(self.nodes):
head.next = ListNode(j)
head = head.next
return tmp.next
運行結果
時間複雜度:,其中 是節點的總數目。
- 遍歷所有的值需花費 的時間。
- 一個穩定的排序算法花費 的時間。
- 遍歷同時創建新的有序鏈表花費 的時間。
空間複雜度: 。
- 排序花費 空間(這取決於你選擇的算法)。
- 創建一個新的鏈表花費 的空間。
解法二:分治算法
分治其實就是不斷縮小其規模,再不斷合併擴大的過程
找到中間點,將其一分爲二,再不停的進行拆分,直至到不能再拆分(規模爲1的時候)便返回。
之後開始合併,合併的代碼借用了合併兩個排序鏈表的代碼。
當兩個規模最小的鏈表合併完後,其規模就變大了,然後不斷重複這個合併過程,直到最終得到一個有序的鏈表。
python代碼
amount = len(lists)
interval = 1
while interval < amount:
for i in range(0, amount - interval, interval * 2):
lists[i] = self.merge2Lists(lists[i], lists[i + interval])
interval *= 2
return lists[0] if amount > 0 else lists
def merge2Lists(self, l1, l2):
head = point = ListNode(0)
while l1 and l2:
if l1.val <= l2.val:
point.next = l1
l1 = l1.next
else:
point.next = l2
l2 = l1
l1 = point.next.next
point = point.next
if not l1:
point.next=l2
else:
point.next=l1
return head.next
運行結果
時間複雜度: ,其中k是鏈表的數目。
- 我們可以在的時間內合併兩個有序鏈表,其中 n是兩個鏈表中的總節點數。
- 將所有的合併進程加起來,我們可以得到:
空間複雜度:O(1).