当前位置:网站首页>【LeetCode】23. 合并K个排序链表(Hard)(Heap / 分治)
【LeetCode】23. 合并K个排序链表(Hard)(Heap / 分治)
2022-07-18 17:58:00 【Lindsay.Lu丶】
- Q23.合并K个排序链表【Hard】
合并 k 个排序链表,返回合并后的排序链表。
说明:请分析和描述算法的复杂度。
样例 0:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
样例 1:
输入: [2->4->null,null,-1->null]
输出: -1->2->4->null
样例 2:
输入: [2->6->null,5->null,7->null]
输出: 2->5->6->7->null
相关题目:839. 合并两个排序的间隔列表791. 合并数字6. 合并排序数组 II4. 丑数 II
// 法1:归并排序 - 写法1(写法2: 两两合并见py法2)
public ListNode mergeKLists_v1(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
return mergeHelper(lists, 0, lists.length-1);
}
private ListNode mergeHelper(ListNode[] lists, int start, int end){
if (start == end)
return lists[start];
int mid = start + end >> 1;
ListNode left = mergeHelper(lists, start, mid);
ListNode right = mergeHelper(lists, mid+1, end);
return mergeTwoLists(left, right);
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
p = l1; // 指针后移
l1 = l1.next;
} else {
p.next = l2;
p = l2; // 指针后移
l2 = l2.next;
}
}
if (l1 != null) p.next = l1;
if (l2 != null) p.next = l2;
return dummy.next;
}
// 法2:最小堆minHeap(每次将K个头结点放入堆,pop出的就是最小的元素)
// - 每次 O(logK) 比较 K个指针求 min, 时间复杂度:O(NlogK)
private Comparator<ListNode> listNodeComparator =
new Comparator<ListNode>() {
@Override
public int compare(ListNode l1, ListNode l2) {
return l1.val - l2.val; // 升序 l1 < l2 < ...
}
};
public ListNode mergeKLists_v2(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
PriorityQueue<ListNode> heap =
new PriorityQueue<>(lists.length, listNodeComparator);
for (ListNode listNode : lists){
if (listNode == null) continue; // 勿漏!!! 形如:[[]]
heap.add(listNode); // 加入的只有每个链表的头部
}
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
while (!heap.isEmpty()) {
ListNode cur = heap.poll(); // 不是pop!
p.next = cur;
p = cur;
if (cur.next != null)
heap.add(cur.next); // 每个链表的next
}
return dummy.next;
}
法2分析:
边栏推荐
- Event capture and bubbling - what is the difference between them?
- Typora图片上传和阿里云OSS对象存储
- Flutter 文字左对齐,中间不留空白
- 理性看待 5G 网络热潮,4G 仍然是主力
- Introduction to unity -- gravity hitting the wall experiment
- The principle difference between active / standby and read / write separation cluster of Damon
- Oracle 19c OCP 1Z0-082认证考试题库(19-23)
- navigateTo传参记录
- Unity introductory learning experiment - control the movement of game objects
- Neo hacker song's award-winning list was announced. Who owns tens of thousands of dollars of gold?
猜你喜欢
Event capture and bubbling - what is the difference between them?
Kotlin函数
Android Studio 中如何安全的删除某个无用的Activity
[mongodb - learning summary]
最大公共子串 && 正则问题
Markdown语法学习资料
【程序、进程、线程、协程的概念和区别,什么是多线程?什么是单线程?】
Have you been bothered by any stupid bug for more than a week?
Spark调度解析
搭建同构(dm-dm)及异构数据库 (dm-oracle,dm-mysql)的 dblink
随机推荐
联发科 MTK 4G/5G 方案的选择
记录一下如何运行MDX文件
Shell 将传参字符串按指定分隔符拆分成数组,并遍历处理
flutter webview 抖动
Leetcode并查集问题汇总
Introduction to pict use case design tool
微信小程序view标签跳转客服对话
ArrayList - reprint
flutter 编译不通过问题
学好这五个走遍天下都不怕
How to use multiple elements in a form
数仓拉链表逻辑
Oracle 19c OCP 1Z0-082认证考试题库(42-50)
大学做过的项目遇到的问题及解决方案总结
Detailed explanation of the underlying principles of list, set and map (mandatory for interview)
Markdown语法学习资料
matlab一些函数
Kotlin程序控制
NVM installation
一招分辨手机短信