此题与合并两个有序链表解法相似;关键在于如何每次快速获得k个链表的最小节点;【使用优先队列(最小堆),里面保存k个链表,链表的首结点都是该链表的最小节点】
头结点的作用:保存链表表头,方便返回,dummy指向链表的尾节点,每次dummy的next指针都指向最小的节点,同时往后走dummy=dummy.next
注意点:队列传入的接口部分实现的比较方法,参数一是最小堆的元素个数,参数二是维持最小堆里元素所实现的比较器,通过这个比较器来决定谁会在堆里
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists==null||lists.length==0)
return null;
PriorityQueue<ListNode> queue = new PriorityQueue(lists.length,new Comparator<ListNode>()
{
@Override
public int compare(ListNode o1,ListNode o2)
{
if(o1.val<o2.val)
return -1;
if(o1.val==o2.val)
return 0;
else
return 1;
}
});
for(ListNode node:lists)
{
if(node!=null)
{
queue.add(node);
}
}
ListNode head=new ListNode(-1);
ListNode dummy = head;
while(queue.size()>0)
{
ListNode minNode=queue.poll();
dummy.next=minNode;
dummy=dummy.next;
minNode=minNode.next;
if(minNode!=null)
{
queue.add(minNode);
}
}
return head.next;
}
}
时间复杂度:往堆里添加元素或取出元素维持堆顶元素最小,时间复杂度logK,每个节点都会添加到堆中 总时间复杂度nlogk,k链表数,n为节点总数