23. 合并K个升序链表
难度困难1151
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
1 | 输入:lists = [[1,4,5],[1,3,4],[2,6]] |
示例 2:
1 | 输入:lists = [] |
示例 3:
1 | 输入:lists = [[]] |
提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i]
按 升序 排列lists[i].length
的总和不超过10^4
解答:
优先队列
heapq
是二叉堆,通常用普通列表实现。heapq
模块是在Python中不错的优先级队列实现。由于heapq在技术上只提供最小堆实现,因此必须添加额外步骤来确保排序稳定性,以此来获得“实际”的优先级队列中所含有的预期特性。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import heapq
q = []
heapq.heappush(q, (2, 'code'))
heapq.heappush(q, (1, 'eat'))
heapq.heappush(q, (3, 'sleep'))
while q:
next_item = heapq.heappop(q)
print(next_item)
# 结果:
# (1, 'eat')
# (2, 'code')
# (3, 'sleep')queue.PriorityQueue
这个优先级队列的实现在内部使用了heapq
,时间和空间复杂度与heapq
相同。区别在于
PriorityQueue
是同步的,提供了锁语义来支持多个并发的生产者和消费者。在不同情况下,锁语义可能会带来帮助,也可能会导致不必要的开销。不管哪种情况,你都可能更喜欢
PriorityQueue
提供的基于类的接口,而不是使用heapq
提供的基于函数的接口。
1 | from queue import PriorityQueue |
其中PriorityQueue可以自定义比较函数:
1 | from queue import PriorityQueue |
题解:
使用heapq解决该问题,每一个链表的第一个节点进入堆进行比较,然后最小的那个取出来扔进新链表,然后最小的那个向后移动一位(80ms)
1 | # Definition for singly-linked list. |
使用PriorityQueue解决问题,速度慢于heapq(144ms):
1 | # Definition for singly-linked list. |
分治
首先实现合并两个链表,然后分治:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
# 合并两个链表的代码
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 and l2:
if l1.val > l2.val:
l1,l2=l2,l1
l1.next=self.mergeTwoLists(l1.next,l2)
return l1 or l2
#调用上面的代码合并两个节点
def mergetwonode(self,node1:ListNode,node2:ListNode)->ListNode:
return self.mergeTwoLists(node1,node2)
#分治
def merge(self,left:int,right:int,lists:List[ListNode])->ListNode:
if left==right:
return lists[left]
if left>right:
return None
mid=left+((right-left)//2)
return self.mergetwonode(self.merge(left,mid,lists),self.merge(mid+1,right,lists))
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if not lists:
return None
return self.merge(0,len(lists)-1,lists)