题目:Merge k Sorted Lists
难度:hard
问题描述:
Merge
k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
将一个已经排序好的链表数组整合成一个新的排序好了的数组。
解题思路:
思路1:每次读出每个链表的头结点值lists[n].val,找到值最小的节点lists[a],加入res,并将该节点的头结点后移一位,list[a]=list[a].next;
重复以上操作,知道所有节点都加入了res。
实现以上代码后,在leetCode运行显示超时,复杂度太高,每加入一个节点都要循环查找n个链表头结点。查看提示tags,看到关键词heap。想到了堆排序,遂有了思路2
思路2:一次读出每个节点,并加入搜索二叉树,然后利用中序遍历,获得从小到大的值并加入res即可。
具体代码如下:
public class h_23_MergeKSortedLists {
ListNode list=new ListNode(0);
ListNode tail=list;
public class ListNode{
int val;
ListNode next;
ListNode(int x){
this.val=x;
}
}
/**********方法一****************/
public ListNode mergeKLists(ListNode[] lists){
if(lists==null) return null;
int x=Integer.MAX_VALUE,jishu=-1;
ListNode head,tail;
//先确定第一位节点
for(int i=0;i
=lists[i].val){
x=lists[i].val;
jishu=i;
}
}
}
if(x!=Integer.MAX_VALUE){
head=lists[jishu];
tail=head;
if(lists[jishu].next!=null){
lists[jishu]=lists[jishu].next;
System.out.println("list["+jishu+"]变为"+lists[jishu].val);
}else{
lists[jishu]=null;
}
// System.out.println("找到第一个="+head.val);
}else{
return null;
}
//每找到下一节点就再次从每个链表的头部找出最小的节点来作为下一节点
while(true){
x=Integer.MAX_VALUE;
for(int i=0;i
=lists[i].val){
x=lists[i].val;
jishu=i;
}
}
}
if(x!=Integer.MAX_VALUE){
tail.next=lists[jishu];
tail=tail.next;
// System.out.println("第"+jishu+"最小");
if(lists[jishu].next!=null){
lists[jishu]=lists[jishu].next;
}else{
lists[jishu]=null;
}
// System.out.println("找到下个="+tail.val);
}else{
return head;
}
}
}
/**************方法二*************************/
//构造搜索二叉树数据结构
//堆排序数据结构
public class BTS{
private Node root;
private class Node{
private int key;
private Node left;
private Node right;
public int N;
public Node(int key,int N){
this.key=key;
this.N=N;
}
}
public int size(){
return size(root);
}
public int size(Node x){
if(x==null) return 0;
else return x.N;
}
//插入数据
public void put(int key){
root=put(root,key);
}
private Node put(Node x,int key){
if(x==null) return new Node(key,1);
int cmp=key-x.key;
if(cmp<=0) x.left=put(x.left,key);
else if(cmp>0) x.right=put(x.right,key);
x.N=size(x.left)+size(x.right)+1;
return x;
}
//通过中序遍历 将每个节点从小到大取出 添入链表
public void print_zhong(Node x){
if(x==null) return ;
print_zhong(x.left);
System.out.println(x.key);
tail.next=new ListNode(x.key);
tail=tail.next;
print_zhong(x.right);
}
}
//基于堆排序的第二方法
public ListNode mergeKLists2(ListNode[] lists) {
BTS bts=new BTS();
if(lists==null){
return null;
}
if(lists.length==1){
return lists[0];
}
for(int i=0;i