您的位置:首页 > 其它

leetcode--23. Merge k Sorted Lists

2017-07-21 00:30 405 查看

题目

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

合并n个有序链表

解法一

可以采用分治法。先把大任务先分成两个子任务,然后递归求子任务,最后回溯回来。有点类似先分后合。这个题目也可以采用这样的算法。即将k个链表平均分成两份,继续划分,直到左边界和右边界相等,返回这个链表,也就是最后会分成剩下一个链表。 然后每两个链表合并,合并之后再合并,回溯回来。最后合并成一个链表。完成。代码如下。(表达不清楚,还请见谅)其中merge是合并两个链表的算法。

public ListNode mergeKLists(ListNode[] lists) {
if(lists == null || lists.length==0) return null;
return partion(lists,0,lists.length-1);
}

public static ListNode partion(ListNode[] lists,int l,int r){
if(l<r){
int m = (l+r)/2;
ListNode l1 = partion(lists,l,m);
ListNode l2 = partion(lists,m+1,r);
return merge(l1,l2);
} else{
return lists[l];
}
}

public static ListNode merge(ListNode l1,ListNode l2){
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val < l2.val){
l1.next = merge(l1.next,l2);
return l1;
}else{
l2.next = merge(l1,l2.next);
return l2;
}
}


解法二

使用优先队列。优先对列底层默认使用最小堆实现的。即从对堆里面取一个数取到的是最小的数。因此我们可以把k个节点放入优先队列中,每次从中取最小的一个。取完再把取出节点的下一节点放进去。因为链表是有序的,因此当优先队列为空时,所有列表都已经遍历完了。

public ListNode mergeKLists(ArrayList<ListNode> lists) {
PriorityQueue<ListNode> heap = new PriorityQueue<ListNode>(10,new Comparator<ListNode>(){
@Override
public int compare(ListNode n1, ListNode n2)
{
return n1.val-n2.val;
}
});
for(int i=0;i<lists.size();i++)
{
ListNode node = lists.get(i);
if(node!=null)
{
heap.offer(node);
}
}
ListNode head = null;
ListNode pre = head;
while(heap.size()>0)
{
ListNode cur = heap.poll();
if(head == null)
{
head = cur;
pre = head;
}
else
{
pre.next = cur;
}
pre = cur;
if(cur.next!=null)
heap.offer(cur.next);
}
return head;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: