1.题目描述:

2.解题思路:

  题意:将K个已经排序的链表合并成一个排序的链表,分析并描述所用算法的复杂度。

  方法一:基于“二分”思想的归并排序。本文用非递归和递归两种方法实现。

  (1)非递归:归并排序”(Merging Sort):将两个或两个以上的有序表组合成一个新的有序表,无论是顺序存储结构还是链式存储结构,对于任何两个长度分别为m和n的有序表,其组合都可在O(m+n)的时间复杂度量级上完成。对于K个有序表,假设共有N个元素,且这些有序表初始状态都不为空,每个有序表平均拥有N/K个元素。最常用的方法是采用“二分”的思想进行两两合并:第一轮循环,有序表lists[0]与lists[(K+1)/2],lists[1]与lists[(K+1)/2+1],lists[2]与lists[(K+1)/2+2]....,lists[K/2-1]与lists[K-1]。这样K个有序表就被组合成了K/2个有序表;第二轮循环后将减少为K/4个有序表;直到组合成一个具有N个元素的有序表。总的时间复杂度:O(NKlogK)。

  (2)递归:思想和上面类似,用的是递归实现。

  方法二:基于优先级队列的“堆排序”。

  在Java中,堆是一种可以自我调整的二叉树,对于最小堆来说,对树执行删除和添加操作,可以让最小元素移动到根节点。在Java中,优先级队列(Priority Queue)便采用了“堆”这种数据结构,PriorityQueue是一个泛型类,它可以保存实现了Comparable接口的类对象,也可以保存在构造器中提供比较器的对象(优先级队列实现排序中也需要比较)。

基于优先级队列,我们可以将K个链表的头结点全部添加到队列,由于优先级队列采用了最小堆数据结构,堆顶为队列的最小元素,我们将其取出添加到结果链表中,取出元素对应的链表下移一个节点,并将这个节点添加到优先级队列中;然后我们继续取出堆顶元素,...,直到优先级队列为空,那么其中所有元素取尽,K个链表的元素已经全部排序到结果链表。

3.Java代码:

(1)归并排序:非递归

 //public class LeetCode23 为测试代码
public class LeetCode23 {
public static void main(String[] args) {
ListNode[] lists=new ListNode[3];
ListNode a1=new ListNode(1);
ListNode a2=new ListNode(4);
ListNode a3=new ListNode(7);
a1.next=a2;
a2.next=a3;
System.out.println("链表a:"+a1.val+"->"+a2.val+"->"+a3.val);
ListNode b1=new ListNode(2);
ListNode b2=new ListNode(5);
ListNode b3=new ListNode(8);
b1.next=b2;
b2.next=b3;
System.out.println("链表b:"+b1.val+"->"+b2.val+"->"+b3.val);
ListNode c1=new ListNode(3);
ListNode c2=new ListNode(6);
ListNode c3=new ListNode(9);
c1.next=c2;
c2.next=c3;
System.out.println("链表c:"+c1.val+"->"+c2.val+"->"+c3.val);
lists[0]=a1;
lists[1]=b1;
lists[2]=c1;
ListNode result=new Solution().mergeKLists(lists);
if(result!=null){
System.out.print("结果链表:"+result.val);
ListNode resultNext=result.next;
while(resultNext!=null){
System.out.print("->"+resultNext.val);
resultNext=resultNext.next;
}
} }
} //class Solution为ac代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len=lists.length;
if(lists==null||len==0) return null;
while(len>1){
int mid=(len+1)/2;//len+1是为了在len为奇数时,mid恰好是正中间那一个
for(int i=0;i<len/2;i++){
lists[i]=merge2Lists(lists[i],lists[mid+i]);
}
len=mid;
}
return lists[0];
} private ListNode merge2Lists(ListNode l1, ListNode l2) {
if(l1==null) return l2;
if(l2==null) return l1;
if(l1.val<l2.val){
l1.next=merge2Lists(l1.next, l2);
return l1;
}
else{
l2.next=merge2Lists(l1, l2.next);
return l2;
}
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}

测试结果:

(2)归并排序:递归

 public class LeetCode23 {
public static void main(String[] args) {
ListNode[] lists=new ListNode[3];
ListNode a1=new ListNode(1);
ListNode a2=new ListNode(4);
ListNode a3=new ListNode(7);
a1.next=a2;
a2.next=a3;
System.out.println("链表a:"+a1.val+"->"+a2.val+"->"+a3.val);
ListNode b1=new ListNode(2);
ListNode b2=new ListNode(5);
ListNode b3=new ListNode(8);
b1.next=b2;
b2.next=b3;
System.out.println("链表b:"+b1.val+"->"+b2.val+"->"+b3.val);
ListNode c1=new ListNode(3);
ListNode c2=new ListNode(6);
ListNode c3=new ListNode(9);
c1.next=c2;
c2.next=c3;
System.out.println("链表c:"+c1.val+"->"+c2.val+"->"+c3.val);
lists[0]=a1;
lists[1]=b1;
lists[2]=c1;
ListNode result=new Solution().mergeKLists(lists);
if(result!=null){
System.out.print("结果链表:"+result.val);
ListNode resultNext=result.next;
while(resultNext!=null){
System.out.print("->"+resultNext.val);
resultNext=resultNext.next;
}
} }
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len=lists.length;
if(lists==null||len==0) return null;
return partion(lists,0,len-1);
} private ListNode partion(ListNode[] lists, int start, int end) {
if(start==end) return lists[start];
if(start<end){
int mid=(start+end)/2;
ListNode left=partion(lists, start, mid);
ListNode right=partion(lists, mid+1, end);
return merge2Lists(left, right);
}else
return null; } private ListNode merge2Lists(ListNode l1, ListNode l2) {
if(l1==null) return l2;
if(l2==null) return l1;
if(l1.val<l2.val){
l1.next=merge2Lists(l1.next, l2);
return l1;
}
else{
l2.next=merge2Lists(l1, l2.next);
return l2;
}
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}

测试结果:

(3)堆排序

 import java.util.Comparator;
import java.util.PriorityQueue; //public class LeetCode23 为测试代码
public class LeetCode23{
public static void main(String[] args) {
ListNode[] lists=new ListNode[3];
ListNode a1=new ListNode(1);
ListNode a2=new ListNode(4);
ListNode a3=new ListNode(7);
a1.next=a2;
a2.next=a3;
System.out.println("链表a:"+a1.val+"->"+a2.val+"->"+a3.val);
ListNode b1=new ListNode(2);
ListNode b2=new ListNode(5);
ListNode b3=new ListNode(8);
b1.next=b2;
b2.next=b3;
System.out.println("链表b:"+b1.val+"->"+b2.val+"->"+b3.val);
ListNode c1=new ListNode(3);
ListNode c2=new ListNode(6);
ListNode c3=new ListNode(9);
c1.next=c2;
c2.next=c3;
System.out.println("链表c:"+c1.val+"->"+c2.val+"->"+c3.val);
lists[0]=a1;
lists[1]=b1;
lists[2]=c1;
ListNode result=new Solution().mergeKLists(lists);
if(result!=null){
System.out.print("结果链表:"+result.val);
ListNode resultNext=result.next;
while(resultNext!=null){
System.out.print("->"+resultNext.val);
resultNext=resultNext.next;
}
} }
} //class Solution为ac代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists==null||lists.length==0) return null;
if(lists.length==1) return lists[0];
PriorityQueue<ListNode> queue=new PriorityQueue<ListNode>(1, new Comparator<ListNode>() {
public int compare(ListNode l1,ListNode l2){
return l1.val-l2.val;
}
});
for(ListNode list:lists){
if(list!=null)
queue.offer(list);
}
ListNode head=new ListNode(0);//建一个辅助结点作为最终所求链表的头节点
ListNode p=head;
while(!queue.isEmpty()){
ListNode node=queue.poll();
p.next=node;
p=p.next;
if(node.next!=null) queue.offer(node.next);
}
return head.next;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}

测试结果:

【LeeCode23】Merge k Sorted Lists★★★的更多相关文章

  1. 【leetcode】Merge k Sorted Lists

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  2. 【Leetcode】【Hard】Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解 ...

  3. 【leetcode】Merge k Sorted Lists(按大小顺序连接k个链表)

    题目:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  4. 【LeetCode练习题】Merge k Sorted Lists

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  5. 【LeetCode每天一题】 Merge k Sorted Lists(合并K个有序链表)

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...

  6. 【LeetCode】【数组归并】Merge k Sorted Lists

    描述 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  7. 【leetcode刷题笔记】Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题 ...

  8. 【leetcode】Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  9. 【leetcode】Merge Two Sorted Lists(easy)

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

随机推荐

  1. IDEA项目搭建四——使用Mybatis实现Dao层

    一.引入mybatis及mysql的jar包 可以从阿里云上面查找版本,db操作放在dao层所以打开该层的pom.xml文件,找到<dependencies>节点增加两个引入 <de ...

  2. 配置ArcGIS Server使用LDAP身份认证

    1.登陆ArcGIS Server Manager,修改站点的安全设置.选择用户和角色来自现有企业系统(LDAP或Windows域). 2.选择LDAP存储类型. 3.填写LDAP用户存储连接信息.主 ...

  3. windows 服务器远程桌面 你的凭据不工作

    一.问题描述   通过windows 远程桌面连接服务器时,输入正确的用户名和密码,点击连接按钮时,提示“你的凭据不工作”,但是其他个别电脑可以通过远程桌面远程到目标服务器.问题描述如下图所示: 二. ...

  4. python函数-匿名函数

    1,匿名函数,故名思意,就是没有名字的函数. def fun(x): return x+x 上述代码的作用就是求x+x的和的函数.如果调用该函数的话,可以使用fun(1)即可.那么lambda函数和上 ...

  5. jquery中使用datepicker限制开始日期小于结束日期

    这里是使用Jquery插件实现的,这段代码来自于网络.感觉很实用,就做笔记记录下来. 原文:http://blog.csdn.net/tianyacao8025/article/details/707 ...

  6. 关于Apache连接数限制的设置

    昨天晚上收到监视团队的电话,说web服务器连不上.(作为DBA,这貌似超出了我的工作范畴啊...) 于是马上VPN连上服务器,发现网络负载均衡下的两台Apache服务器都没有响应,而服务器OS层面上正 ...

  7. VScode开发Vue项目,关闭eslint代码检查,以及相关配置

    Vue初始化项目时如果不小心安装了js 语法检测 功能,撸码时一个空格不对就会各种报错 个人感觉这个语法检测功能很有点过于严格,用起来十分难受,所以果断关闭eslint,找到webpack.base. ...

  8. Web Services 根据wsdl生成代理类

    生成代理类步骤: 一:找到Visual Studio 的工具文件夹 二:用管理员方式打开本机工具命令提示 三:输入要执行的脚本 wsdl /language:C# /n:xxxx.HermesMobi ...

  9. 经典Paxos算法笔记

    介绍 Paxos算法是一个高容错性的分布式一致性算法.去年学习过Paxos算法,一直没将整理到博客.现在将经典Paxos算法相关内容整理到博客上. 经典Paxos算法本身也并不是太难理解,Lampor ...

  10. python第二十九课——文件读写(写数据的操作)

    演示写数据的操作: 结论:往文件中写入数据,如果文件不存在,先创建文件,再写入内容 #1.打开文件 fw=open(r'd.txt','w',encoding='utf-8') #2.写数据操作 fw ...