LeetCode 23. 合并K个排序链表
2020-04-26 07:59:55来源:博客园 阅读 ()
LeetCode 23. 合并K个排序链表
我的LeetCode:https://leetcode-cn.com/u/ituring/
我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii
LeetCode 23. 合并K个排序链表
题目
合并?k?个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
? 1->4->5,
? 1->3->4,
? 2->6
]
输出: 1->1->2->3->4->4->5->6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
很明显的topK问题;
- 使用最小堆或者优先队列;
- 分治,折半合并排序;
思路1-使用优先队列/最小堆
步骤:
- 使用PriorityQueue优先队列,需要实现Comparator接口的compare方法;
- 不断取出头部节点对象拼接新链表;
算法复杂度: n为节点总数
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(nlogk\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(k\right)}} $
思路2-分治折半合并排序
步骤:
- 每次折半首位对应的链表合并排序,结果给到靠首部的位置;
- 每次折半排序后的长度重置为(n+1)/2,解决长度为奇偶的问题;
算法复杂度: n为节点总数
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(nlogk\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(logk\right)}} $ 递归时栈的深度
算法源码示例
package leetcode;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* @author ZhouJie
* @date 2020年1月10日 下午8:26:09
* @Description: 23. 合并K个排序链表
*
*/
public class LeetCode_0023 {
}
// Definition for singly-linked list.
class ListNode_0023 {
int val;
ListNode_0023 next;
ListNode_0023(int x) {
val = x;
}
}
class Solution_0023 {
/**
* @author ZhouJie
* @date 2020年1月10日 下午8:48:38
* @Description: TODO(方法简述)
* @return ListNode_0023
* @UpdateUser-UpdateDate:[ZhouJie]-[2020年1月10日 下午8:48:38]
* @UpdateRemark:1-使用优先队列
*
*/
public ListNode_0023 mergeKLists_1(ListNode_0023[] lists) {
if (lists == null) {
return null;
}
// 优先队列,非基础类型需要重写比较器
PriorityQueue<ListNode_0023> queue = new PriorityQueue<ListNode_0023>(new Comparator<ListNode_0023>() {
public int compare(ListNode_0023 o1, ListNode_0023 o2) {
return o1.val - o2.val;
}
});
for (ListNode_0023 node : lists) {
if (node != null) {
queue.add(node);
}
}
ListNode_0023 head, now;
head = now = null;
while (!queue.isEmpty()) {
ListNode_0023 node = queue.poll();
if (head == null) {
head = now = node;
} else {
now.next = node;
now = node;
}
if (node.next != null) {
queue.add(node.next);
}
}
return head;
}
/**
* @author ZhouJie
* @date 2020年1月10日 下午9:03:07
* @Description: TODO(方法简述)
* @return ListNode_0023
* @UpdateUser-UpdateDate:[ZhouJie]-[2020年1月10日 下午9:03:07]
* @UpdateRemark:2-分治思想,不断折半合并,直至为一个;
*
*/
public ListNode_0023 mergeKLists_2(ListNode_0023[] lists) {
int len;
if (lists == null || (len = lists.length) == 0) {
return null;
}
while (len > 1) {
for (int i = 0; i < len / 2; i++) {
// 对半合并,后一半合并到前一半
lists[i] = mergeHelper(lists[i], lists[len - 1 - i]);
}
len = (len + 1) / 2;
}
return lists[0];
}
/**
* @author: ZhouJie
* @date: 2020年2月4日 下午2:45:50
* @param: @param l1
* @param: @param l2
* @param: @return
* @return: ListNode_0023
* @Description: 合并两个有序链表辅助方法
*
*/
private ListNode_0023 mergeHelper(ListNode_0023 l1, ListNode_0023 l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeHelper(l1.next, l2);
return l1;
} else {
l2.next = mergeHelper(l1, l2.next);
return l2;
}
}
}
原文链接:https://www.cnblogs.com/izhoujie/p/12779790.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spire.Cloud.SDK for Java 合并、拆分Excel单元格 2020-06-09
- 合并有序两个单链表,合并后链表依然有序 2020-06-02
- LeetCode 287. 寻找重复数 2020-05-31
- LeetCode 5. 最长回文子串 2020-05-22
- LeetCode 21. 合并两个有序链表 2020-05-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash