将多个有序链表拼接成一个,思路同拼接两个链表,先比较两个(或k个)链表的表头,最小的表头节点摘下,继续比较,直到所有链表的节点都被摘空为止。基于算法的效率考虑,每次比较k个链表的表头,只有最小的表头节点被拿走,下一次拿该表头节点的下一个节点和其余k-1个比较。此时对k个节点的排序不用堆排序都对不起当年在算法课上猛打瞌睡的自己。
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
ArrayList<ListNode> nodeListHeap=new ArrayList<ListNode>();
public ListNode mergeKLists(ListNode[] lists) {
ListNode node=new ListNode(0);
ListNode head=node;
if(lists==null){
return null;
}
createHeap(lists);
while(nodeListHeap.size()>1){
if(nodeListHeap.get(0)==null){
return null;
}
node.next=nodeListHeap.get(0);
node=node.next;
//此处处理的要点是截断不能破坏堆结构,使用策略用常见的堆策略,即把最后一个放到第一个位置
if(nodeListHeap.get(0).next==null){
nodeListHeap.set(0,nodeListHeap.get(nodeListHeap.size()-1));
nodeListHeap.remove(nodeListHeap.size()-1);
}else{
nodeListHeap.set(0,nodeListHeap.get(0).next);
}
adjustHeap(0);
}
if(nodeListHeap.size()==1){
node.next=nodeListHeap.get(0);
}
return head.next;
}
public void createHeap(ListNode[] lists){
for(ListNode node:lists){
if(node!=null){
nodeListHeap.add(node);
}
}
if(nodeListHeap.size()<=1){
return;
}
int index=(nodeListHeap.size()-1)/2;
while(index>=0){
int leftparent=index*2+1;
int rightparent=index*2+2;
ListNode tempNode=null;
if(rightparent<nodeListHeap.size()&&nodeListHeap.get(leftparent).val>nodeListHeap.get(rightparent).val){
if(nodeListHeap.get(index).val>nodeListHeap.get(rightparent).val){
ListNode nodetemp=nodeListHeap.get(index);
nodeListHeap.set(index, nodeListHeap.get(rightparent));
nodeListHeap.set(rightparent, nodetemp);
adjustHeap(rightparent);
}
}else if(leftparent<nodeListHeap.size()&&nodeListHeap.get(index).val>nodeListHeap.get(leftparent).val){
ListNode nodetemp=nodeListHeap.get(index);
nodeListHeap.set(index, nodeListHeap.get(leftparent));
nodeListHeap.set(leftparent, nodetemp);
adjustHeap(leftparent);
}
index--;
}
}
public void adjustHeap(int start){
int index=start;
while(index<(nodeListHeap.size()+1)/2){
int leftparent=index*2+1;
int rightparent=index*2+2;
if(rightparent<nodeListHeap.size()&&nodeListHeap.get(leftparent).val>nodeListHeap.get(rightparent).val){
if(nodeListHeap.get(index).val>nodeListHeap.get(rightparent).val){
ListNode nodetemp=nodeListHeap.get(index);
nodeListHeap.set(index, nodeListHeap.get(rightparent));
nodeListHeap.set(rightparent, nodetemp);
index=rightparent;
}else{
return;
}
}else if(leftparent<nodeListHeap.size()){
if(nodeListHeap.get(index).val>nodeListHeap.get(leftparent).val){
ListNode nodetemp=nodeListHeap.get(index);
nodeListHeap.set(index, nodeListHeap.get(leftparent));
nodeListHeap.set(leftparent, nodetemp);
index=leftparent;
}else{
return;
}
}else{
return;
}
}
return;
}
}