题目
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入: lists = [[1,4,5],[1,3,4],[2,6]]
输出: [1,1,2,3,4,4,5,6]
解释: 链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入: lists = []
输出: []
示例 3:
输入: lists = [[]]
输出: []
提示:
k == lists.length0 <= k <= 10^40 <= lists[i].length <= 500-10^4 <= lists[i][j] <= 10^4lists[i]按 升序 排列lists[i].length的总和不超过10^4
思路
解法一: 顺序合并
顺序合并,第一个和第二个合并后的链表res,再和第三个链表合并,直到合并到第K个,完成最终的所有链表合并。
注意:合并时候的变量赋值。
代码一:顺序合并
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
if len(lists) == 0:
return
if len(lists) == 1:
return lists[0]
res = lists[0]
for i in range(1, len(lists)):
res = merge(res, lists[i])
return res
def merge(l1, l2):
"""合并2个链表"""
if l1 is None or l2 is None:
return l1 or l2
head = l1 if l1.val < l2.val else l2
res = head
cur1 = l1.next if head == l1 else l2.next
cur2 = l2 if head == l1 else l1
while cur1 is not None and cur2 is not None:
if cur1.val <= cur2.val:
head.next = cur1
cur1 = cur1.next
else:
head.next = cur2
cur2 = cur2.next
head = head.next
# 处理公共长度之外的链表
if cur1 is not None:
head.next = cur1
if cur2 is not None:
head.next = cur2
return res
解法二: 分治+合并
分治法,类似于归并排序,将k个链表区分为left,right,直到left和right都只包含一个链表,然后进行链表的整合。
代码二: 分治+合并
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
if len(lists) == 0:
return
if len(lists) == 1:
return lists[0]
return merge(0, len(lists)-1, lists)
def merge(l, r, nodes):
"""分治处理主函数"""
if l == r:
return nodes[l]
mid = (l + r) >> 1
left = merge(l, mid, nodes)
right = merge(mid+1, r, nodes)
if left is None or right is None:
return left or right
head = left if left.val <= right.val else right
res = head
cur1 = left.next if head == left else right.next
cur2 = left if head == right else right
while cur1 is not None and cur2 is not None:
if cur1.val <= cur2.val:
head.next = cur1
cur1 = cur1.next
else:
head.next = cur2
cur2 = cur2.next
head = head.next
if cur1 is not None:
head.next = cur1
if cur2 is not None:
head.next = cur2
return res
解法三: 优先队列
利用优先队列,维护当前没被合并元素最前面的一个,K个链表,最多就有K个满足这样的元素,利用优先队列,每次找到当前的最小结点,然后将这个节点移除,将该节点的下一个节点加入优先队列。一直轮询获取当前的最小节点,直到这个优先队列为空,返回结果。
代码三: 优先队列轮询
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
from queue import PriorityQueue
class Status:
def __init__(self, val, ptr):
self.val = val
self.ptr = ptr
def __lt__(self, other):
return self.val < other.val
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
if len(lists) == 0:
return
if len(lists) == 1:
return lists[0]
# Python 优先队列,内部是栈实现,线程安全
q = PriorityQueue()
for node in lists:
if node is not None:
q.put(Status(node.val, node))
# 设置一个哨兵变量
head = ListNode(0)
tail = head
while q.qsize() > 0:
# 取到最小的值和节点
cur = q.get()
tail.next = cur.ptr
tail = tail.next
if cur.ptr.next is not None:
q.put(Status(cur.ptr.next.val, cur.ptr.next))
return head.next