这个题解使用了优先队列(最小堆)来合并 K 个有序链表。首先,我们创建一个虚拟头节点 dummy,并将指针 p 指向 dummy。然后,我们遍历所有的链表头节点,将非空的头节点的值、链表编号和节点本身作为一个三元组放入最小堆中。接下来,我们不断从最小堆中取出最小值节点,将其添加到合并后的链表中,并将指针 p 向后移动。如果取出的节点还有下一个节点,我们将下一个节点的信息放入最小堆中。重复这个过程,直到最小堆为空。最后,我们返回 dummy.next,即合并后的链表的真正头节点。
时间复杂度: O((n + k) * log(k))
空间复杂度: O(k)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
import heapq
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
dummy = ListNode() # 创建虚拟头节点
p = dummy # 指针 p 初始指向虚拟头节点
h = [] # 创建最小堆
# 遍历所有链表的头节点
for i, head in enumerate(lists):
if head is None:
continue
# 将非空头节点的值、链表编号和节点本身放入最小堆
heapq.heappush(h, [head.val, i, head])
# 不断从最小堆中取出节点,直到堆为空
while len(h) > 0:
_, i, head = heapq.heappop(h) # 取出最小值节点
p.next = head # 将节点添加到合并后的链表中
p = p.next # 指针 p 向后移动
head = head.next # 取出节点的下一个节点
if head is not None:
# 如果下一个节点不为空,将其放入最小堆
heapq.heappush(h, [head.val, i, head])
return dummy.next # 返回合并后的链表的真正头节点