码迷,mamicode.com
首页 > 其他好文 > 详细

Merge k Sorted Lists

时间:2014-10-01 12:19:11      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   使用   ar   for   sp   

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

 

方法一:暴力破解,1和2合并,合并后再和3合并,合并后再和4合并。。。如此下去一直将所有链表节点全部合并完。

复杂度分析,假设有k个链表,每个链表平均长度为n

1和2合并,扫描节点个数为 2n

12和3合并,扫描节点个数为 3n

123和4合并,扫描节点个数为 4n

......

123..k-1和k合并,扫描节点个数为 kn

那么总得扫描节点个数为 n(2++3+4+5+6+...+k),时间复杂度为 O(nk2),铁定超时

 

方法二:使用分治法,貌似包治百病,假设有k个链表,每个链表有n个节点,那么就将k个链表分成两部分,每部分都是k/2个链表,先合并k/2个链表,再回来合并k个链表,递推公式为 T(k) = 2T(k/2) + T(nk),使用主定理公式 时间复杂度为 O(nklogk)

可以利用迭代的方式,例如:有链表0,1,2,3,4,5,先合并03,14,25,将结果分别存放在0,1,2中,然后再合并02,结果存在0中,最后在合并01,结果存放在0中,那么lists[0]就是所要求的,代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *mergeKLists(vector<ListNode *> &lists) {
12         if( lists.empty() ) return NULL;
13         int n = lists.size();
14         while( n>1 ) {
15             int k = (n+1)/2;
16             for(int i=0; i<n/2; ++i)
17                 lists[i] = mergeLists(lists[i], lists[i+k]);
18             n = k;
19         }
20         return lists[0];
21     }
22     
23     ListNode* mergeLists(ListNode* lhs, ListNode* rhs) {    //合并两链表
24         if( !lhs ) return rhs;
25         if( !rhs ) return lhs;
26         ListNode node(-1);
27         ListNode* pre = &node;
28         while( lhs && rhs ) {
29             if( lhs->val < rhs->val ) {
30                 pre->next = lhs;
31                 lhs = lhs->next;
32             }
33             else {
34                 pre->next = rhs;
35                 rhs = rhs->next;
36             }
37             pre = pre->next;
38         }
39         pre->next = lhs ? lhs : rhs;
40         return node.next;
41     }
42 };

 

方法三:维护一个k个大小的小根堆,首先将每个链表的第一个节点push进堆中,然后进入以下循环:取堆中最小元素,放入该元素的下一个节点至对中,直至堆为空

依然假设k个链表,每个链表n个节点,那么共需要访问nk个节点,每次放入一个节点到堆中需要logk的时间,那么时间复杂度为O(nklongk)

 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     struct cmp {
12         bool operator()(const ListNode* lhs, const ListNode* rhs) const {
13             return lhs->val > rhs->val;
14         }
15     };
16     
17 public:
18     ListNode *mergeKLists(vector<ListNode *> &lists) {
19         if( lists.empty() ) return NULL;
20         priority_queue<ListNode*, vector<ListNode*>, cmp> pq;   //构造最小堆
21         for(int i=0; i<lists.size(); ++i) { //初始化,先将每个链表的第一个节点放入堆中
22             if( lists[i] ) {
23                 pq.push(lists[i]);
24                 lists[i] = lists[i]->next;
25             }
26         }
27         ListNode node(-1);
28         ListNode* pre = &node;
29         while( !pq.empty() ) {
30             pre->next = pq.top();
31             pq.pop();
32             pre = pre->next;
33             if( pre->next ) pq.push(pre->next); //将取出的节点的下一个节点放入堆中
34         }
35         pre->next = 0;
36         return node.next;
37     }
38 };

 

Merge k Sorted Lists

标签:des   style   blog   color   io   使用   ar   for   sp   

原文地址:http://www.cnblogs.com/bugfly/p/4003131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!