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

Merge k Sorted Lists leetcode

时间:2015-08-20 01:17:03      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

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

 
题目意思就是合并多个有序链表!采用分治递归!
第一种思路分析:分而治之,不断划分,直到变成两个有序链表合并的子问题!归并的动态图如右图所示:技术分享
 
本题建立在合并两个有序链表算法的基础之上,不断合并两个有序子链表,直到整个子链表合而为一。这道题目在分布式系统中非常常见,来自不同client的sorted list要在central server上面merge起来。
我们来分析一下上述算法的时间复杂度。假设总共有k个list,每个list的最大长度是n,那么运行时间满足递推式T(k) = 2T(k/2)+O(n*k)。根据主定理,可以算出算法的总复杂度是O(nklogk)。如果不了解主定理的朋友,可以参见 主定理-维基百科 。空间复杂度的话是递归栈的大小O(logk)。 
代码实现如下:
技术分享
 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 
 5 struct ListNode {
 6     int val;
 7     ListNode *next;
 8     ListNode(int x) : val(x), next(NULL) {}
 9 };
10 
11 class Solution {
12 public:
13     ListNode* mergeKLists(vector<ListNode*>& lists) 
14     {
15         if (lists.size() == 0)
16             return NULL;
17         if (lists.size() == 1)
18             return lists[0];
19         //vector<ListNode*> res;
20         while (lists.size()!=1)
21         {
22             ListNode*temp= mergeTwoLists(lists[0], lists[1]);
23             lists.push_back(temp);
24             lists.erase(lists.begin());
25             lists.erase(lists.begin());
26         }
27         return lists[0];
28 
29     }
30     ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
31     {
32         if (!l1)
33             return l2;
34         if (!l2)
35             return l1;
36         ListNode n1(-1);
37         n1.next = l1;
38         ListNode *ptr1 = l1, *pre1, *ptr2 = l2, *b2;
39         pre1 = &n1;
40         while (ptr2)
41         {
42             b2 = ptr2->next;
43             if (ptr1->val < ptr2->val)
44             {
45                 ptr1 = ptr1->next;
46                 pre1 = pre1->next;///
47                 if (ptr1 == NULL)//这儿必须让其终止!否则运行会出错的
48                     break;
49             }
50             else
51             {
52                 pre1->next = ptr2;
53                 ptr2->next = ptr1;
54                 ptr2 = b2;
55                 pre1 = pre1->next;///
56             }
57         }
58         if (ptr2 != NULL)
59             pre1->next = ptr2;
60         return n1.next;
61     }
62 };
63 
64 int main()
65 {
66     Solution test;
67 
68     vector<ListNode*> val;
69     ListNode *n1 = NULL;
70     ListNode n2(-1),n3(5),n4(11);
71     n2.next = &n3;
72     n3.next = &n4;
73     ListNode *n5 = NULL;
74     ListNode n6(6), n7(10);
75     n6.next = &n7;
76     val.push_back(n1);
77     val.push_back(&n2);
78     val.push_back(n5);
79     val.push_back(&n6);
80     //cout << "the size of val:" << val.size() << " " << val.capacity() << endl;
81     ListNode* result = test.mergeKLists(val);
82     while (result)
83     {
84         cout << result->val << " ";
85         result = result->next;
86     }
87     return 0;
88 }
View Code

 

第二种思路分析(用到了堆这种数据结构):思路比较难想到,但是其实原理比较简单。维护一个大小为k的堆,每次取堆顶的最小元素放到结果中,然后读取该元素的下一个元素放入堆中,重新维护好。因为每个链表是有序的,每次又是去当前k个元素中最小的,所以当所有链表都读完时结束,这个时候所有元素按从小到大放在结果链表中。这个算法每个元素要读取一次,即是k*n次,然后每次读取元素要把新元素插入堆中要logk的复杂度,所以总时间复杂度是O(nklogk)。空间复杂度是堆的大小,即为O(k)。

 
 
 
 
 

Merge k Sorted Lists leetcode

标签:

原文地址:http://www.cnblogs.com/chess/p/4743881.html

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