[LeetCode] Merge K Sorted Linked Lists

题目链接: https://oj.leetcode.com/problems/merge-k-sorted-lists/

 

问题:

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

 

解题思路:

方法一:暴力破解

思路:

将列表一个一个地合并(例如:lists = [l1, l2, l3, l4],首先合并l1和l2,然后将合并后的结果与l3合并,…)

复杂度分析:

时间:

假设有k个列表,每个列表的长度为n,需要k-1次合并操作,第1次操作将2个长度为n的列表合并,最多需要n+n次比较,第二次操作将一个长度为2n和一个长度为n的列表合并,最多需要2n+n次比较,后一次合并需要的最多比较次数比前一次合并多n,所以总的比较次数为 2n + 3n +4n + … + kn = n(k(k+1)/2 - 1) = O(nk^2)

 

方法二:运用小顶堆

思路:

小顶堆的大小为k

1)首先用每个列表的最小元素初始化堆;

2)从堆中返回最小元素之后将它所在的列表中下一个元素插入堆中;

3)重复2)中操作,直到所有列表为空

复杂度分析:

时间:

总共有nk个元素,将每个元素插入堆的操作时间复杂度为O(logk)。

所以,总时间复杂度为O(nklogk)

空间:

额外分配的堆空间为O(k)

 1     private static final Comparator<ListNode> listComparator = new Comparator<ListNode>(){
 2         @Override
 3         public int compare(ListNode x, ListNode y) {
 4             return x.val - y.val;
 5         }
 6     };
 7     
 8     public ListNode mergeKLists(ListNode[] lists) {
 9         if(lists.length == 0){
10             return null;
11         }
12         Queue<ListNode> queue = new PriorityQueue<>(lists.length, listComparator);
13         
14         for(ListNode node: lists){
15             if(node != null){
16                 queue.add(node);
17             }
18         }
19         
20         ListNode dummyHead = new ListNode(0);
21         ListNode p = dummyHead;
22         while (!queue.isEmpty()){
23             ListNode node = queue.poll();
24             p.next = node;
25             p = p.next;
26             if(node.next != null){
27                 queue.add(node.next);
28             }
29         }
30         return dummyHead.next;      
31     }  

 

方法三:分而治之

思路:

采用两两合并的方法

列表数目变化为:k -> k/2 -> k/4 -> … -> 2 -> 1

同时,列表长度变化为: n -> 2n -> 4n -> … -> n * 2^logk 

复杂度分析:

时间:

k * n + (k / 2) *2n + … +  n * 2^logk  * 1

= nk + nk + …+ nk

= nklogk

总时间复杂度为O(nklogk)

空间:

O(1)

 1         public ListNode mergeKLists(ListNode[] lists) {
 2         if(lists.length == 0){
 3             return null;
 4         }
 5         int end = lists.length - 1;
 6         while(end > 0){
 7             int begin = 0;
 8             while(begin < end){
 9                 lists[begin] = merge2Lists(lists[begin], lists[end]);
10                 begin++;
11                 end--;
12             }
13         }
14         return lists[0];
15     }
16     
17     private ListNode merge2Lists(ListNode l1, ListNode l2){
18         ListNode dummyHead = new ListNode(0);
19         ListNode p = dummyHead;
20         while(l1 != null && l2 != null){
21             if(l1.val < l2.val){
22                 p.next = l1;
23                 l1 = l1.next;
24             }else{
25                 p.next = l2;
26                 l2 = l2.next;
27             }
28             p = p.next;
29         }
30         if(l1 != null){
31             p.next = l1;
32         }
33         if(l2 != null){
34             p.next = l2;
35         }
36         return dummyHead.next;
37     }
38     

 

 

posted @ 2016-08-19 17:15  沫沫_fun  阅读(244)  评论(0)    收藏  举报