Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
回顾下算法课上学过的Heap, 维持一个min Heap, 时间复杂度是 O (log n), 原因是每次将添加到heap中的值和上面比较,如果比上面的小,就交换。
如果我们用merge sort的思路,也可以,以后把代码贴出来,先写这个。
思路:利用最小堆的性质,每次拿出来的都是最小的数,那么我们可以把lists中的那些链表的头head,全部放到堆中。这样就解决了我们的问题,因为虽然每个链表都排序好了,
但是你不知道各个链表中哪个数大哪个数小,堆的作用体现出来了。
有了堆,我们维持这个堆就好了:每次拿出最小的,然后在最小的点的那条链表中,把最小的节点(也就是链表的头)删去,把这条链表的第二个点当做头,放到堆中,然后堆又排了序。
为了持续移除,那我们就需要一个循环,就是当堆不为空的时候,做以上操作。当堆为了空,所有的元素也就都弄好了。
注意:因为ListNode是我们自己的类,heap的java实现是ProrityQueue,根据API文档得知,它是按自然顺序 ,我们需要用比较器排序,在建立对象时,构造方法中需要传递Compartor进去,实现也很简单.
代码如下
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if(lists.size()==0) return null;
PriorityQueue<ListNode> queue= new PriorityQueue<ListNode>(lists.size(),new MyComparator());
for(int i=0;i<lists.size();i++){
ListNode a=lists.get(i);
if(a!=null){
queue.add(lists.get(i));}
}
ListNode mergedList=new ListNode(0);
ListNode cur=mergedList;
while(!queue.isEmpty())
{
ListNode minheap=queue.poll();
ListNode next=minheap.next;
cur.next=new ListNode(minheap.val);
minheap.next=null;
if(next!=null){
queue.offer(next);
}
cur=cur.next;
}
return mergedList.next;
}
public class MyComparator implements Comparator<ListNode> {
public int compare(ListNode l1, ListNode l2){
return l1.val-l2.val;
}
}
}