题目描述
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
分析
`N`:链表总结点数。
`K`:链表个数。
方法一:暴力解法,将所有链表的所有值存入数组中,快排排序,再将排序好的建立节点连接。
时间复杂度O(NlogN)
空间复杂度O(N)
方法二:优先队列优化,我们需要维护当前每个链表没有被合并的元素的最前面一个,K
个链表就最多有 K
个满足这样条件的元素,每次在这些元素里面选取 val
属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这个过程。
时间复杂度:O(NlogK)
空间复杂度:O(K)
方法三:分治合并,
- 将 K 个链表配对并将同一对中的链表合并;
- 第一轮合并以后,K 个链表被合并成了 k 2 \frac{k}{2} 2k 个链表,平均长度为 2 n k \frac{2n}{k} k2n ,然后是 k 4 \frac{k}{4} 4k 个链表 k 8 \frac{k}{8} 8k 个链表等等;
- 重复这一过程,直到我们得到了最终的有序链表。
代码
/*
方法一:暴力解法。
*/
# 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:
nums = []
for node in lists:
while node:
nums.append(node.val)
node = node.next
nums.sort()
pre = ListNode(-1)
node = pre
for i in nums:
node.next = ListNode(i)
node = node.next
return pre.next
/*
方法二:优先队列
*/
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists):
import heapq
heap, cur = [], [] #初始化优先队列,建立链表索引
for index, node in enumerate(lists):
if node:
heapq.heappush(heap, (node.val, index))
cur.append(node)
pre = ListNode(-1)
node = pre
while heap:
val, index = heapq.heappop(heap)
node.next = ListNode(val)
node = node.next
cur[index] = cur[index].next
if cur[index]:
heapq.heappush(heap, (cur[index].val, index))
return pre.next
/*
方法三:分治归并
*/
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeKLists(self, lists):
length = len(lists)
if length==0:
return None
interval = 1
while interval<length:
for i in range(0, length-interval, interval*2):
lists[i] = self.Merge(lists[i], lists[i+interval])
interval *= 2
return lists[0]
def Merge(self, pHead1, pHead2):
if not pHead1:
return pHead2
if not pHead2:
return pHead1
pMergeHead = None
if pHead1.val < pHead2.val:
pMergeHead = pHead1
pMergeHead.next = self.Merge(pHead1.next, pHead2)
else:
pMergeHead = pHead2
pMergeHead.next = self.Merge(pHead1, pHead2.next)
return pMergeHead