题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 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.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i]
按 升序 排列lists[i].length
的总和不超过10^4
解题思路
要将多个有序链表合并成一个有序链表,可以使用优先队列(最小堆)来实现,这样能够有效地将多个链表中的最小节点逐步合并,最终形成一个有序的链表。
- 使用优先队列来存储每个链表的头节点。优先队列能够保证每次从多个链表中取出的节点都是当前最小的节点。
- 将每个链表的头节点加入优先队列。
- 每次从优先队列中取出最小节点,并将该节点的下一个节点加入优先队列。
- 重复上述步骤,直到所有节点都被处理完。
复杂度分析
-
时间复杂度:对于每个节点的插入和删除操作,优先队列的时间复杂度为 O(log k),其中 k 是链表的数量。总的时间复杂度为 O(N log k),其中 N 是所有节点的总数。
-
空间复杂度:空间复杂度主要取决于优先队列的存储空间,最坏情况下为 O(k)。
代码实现
package org.zyf.javabasic.letcode.hot100.list;
import org.zyf.javabasic.letcode.list.base.ListNode;
import java.util.PriorityQueue;
/**
* @program: zyfboot-javabasic
* @description: 合并 K 个升序链表 (困难)
* @author: zhangyanfeng
* @create: 2024-08-22 10:32
**/
public class MergeKListsSolution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
// 创建优先队列,并指定排序规则为节点值的升序
PriorityQueue<ListNode> pq = new PriorityQueue<>((a, b) -> a.val - b.val);
// 将每个链表的头节点加入优先队列
for (ListNode list : lists) {
if (list != null) {
pq.offer(list);
}
}
// 创建一个哨兵节点,方便操作
ListNode dummy = new ListNode(0);
ListNode current = dummy;
// 逐步从优先队列中取出最小节点,加入结果链表
while (!pq.isEmpty()) {
ListNode minNode = pq.poll();
current.next = minNode;
current = current.next;
// 如果最小节点有下一个节点,将其加入优先队列
if (minNode.next != null) {
pq.offer(minNode.next);
}
}
return dummy.next;
}
public static void main(String[] args) {
MergeKListsSolution solution = new MergeKListsSolution();
// 示例 1
ListNode l1 = new ListNode(1);
l1.next = new ListNode(4);
l1.next.next = new ListNode(5);
ListNode l2 = new ListNode(1);
l2.next = new ListNode(3);
l2.next.next = new ListNode(4);
ListNode l3 = new ListNode(2);
l3.next = new ListNode(6);
ListNode[] lists = {l1, l2, l3};
ListNode mergedList = solution.mergeKLists(lists);
printList(mergedList); // 输出:[1, 1, 2, 3, 4, 4, 5, 6]
// 示例 2
ListNode[] emptyLists = {};
ListNode mergedList2 = solution.mergeKLists(emptyLists);
printList(mergedList2); // 输出:[]
// 示例 3
ListNode[] singleEmptyList = {null};
ListNode mergedList3 = solution.mergeKLists(singleEmptyList);
printList(mergedList3); // 输出:[]
}
// 打印链表
public static void printList(ListNode head) {
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
System.out.println();
}
}