Leetcode OJ: Merge Two Sorted Lists、Merge k Sorted Lists

这一篇是两个全集,从2个排序列表到k个排序列表。

先从2个入手。

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

思路跟数组时类似,主要都是比较、链表插入操作。

代码如下:

 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 *mergeTwoLists(ListNode *l1, ListNode *l2) {
12         ListNode* ret = NULL;
13         ListNode* pre = NULL;
14         while (l1 != NULL && l2 != NULL) {
15             if (l1->val < l2->val) {
16                 ListNode* tmp = l1->next;
17                 l1->next = NULL;
18                 if (ret == NULL) {
19                     ret = l1;
20                     pre = ret;
21                 } else {
22                     pre->next = l1;
23                     pre = l1;
24                 }
25                 l1 = tmp;
26             } else {
27                 ListNode* tmp = l2->next;
28                 l2->next = NULL;
29                 if (ret == NULL) {
30                     ret = l2;
31                     pre = ret;
32                 } else {
33                     pre->next = l2;
34                     pre = l2;
35                 }
36                 l2 = tmp;
37             }
38         }
39         if (l1 != NULL) {
40             // 判断l1、l2中是否存在空链表
41             if (pre != NULL)
42                 pre->next = l1;
43             else
44                 ret = l1;
45         }
46         if (l2 != NULL) {
47             // 判断l1、l2中是否存在空链表
48             if (pre != NULL)
49                 pre->next = l2;
50             else
51                 ret = l2;
52         }
53         return ret;
54     }
55 };

别忘了检查存在空链表的情况。空间复杂度为O(1),时间复杂度为O(m+n)。

由2个列表变成k的列表又有什么变化呢?

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

按照以上的思路,还是要比较,只是k个List一起比较。

如果是求最大值,最简单的情况就是每个list的头都比较一下,即进行k次比较,要合并完,复杂度为O(k(m+n))。

但是每次比较k次是不是有点慢呢?在这里,我们需要的是每次都得到最大值,第一反应就想到堆了。

于是思路就来了:

1. 先给各List头列一个小根堆

2. 取top,调整,把top插入到输出的链表中,然后把top->next插入堆中,循环这一步至堆空为止。

这里我们直接就用priority_queue,另外还需要定义一个比较类。代码如下:

 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 
10 // 小根堆的比较类
11 class Greater {
12 public:
13     bool operator() (const ListNode* a, const ListNode* b) const {
14         return a->val > b->val;
15     }
16 };
17 
18 class Solution {
19 public:
20     
21     ListNode *mergeKLists(vector<ListNode *> &lists) {
22         priority_queue<ListNode*, vector<ListNode*>, Greater> heap;
23         // 先把非NULL的ListNode给清掉,放进堆中
24         for (vector<ListNode*>::iterator it = lists.begin();
25             it != lists.end(); ++it) 
26         {
27             if ((*it) != NULL)
28                 heap.push(*it);
29         }
30         ListNode* head = NULL;
31         ListNode* pre = NULL;
32         while (!heap.empty()) {
33             ListNode* tmp = heap.top();
34             heap.pop();
35             if (tmp->next != NULL)
36                 heap.push(tmp->next);
37             if (head == NULL) {
38                 head = tmp;
39                 pre = tmp;
40                 continue;
41             }
42             pre->next = tmp;
43             pre = tmp;
44         }
45         return head;
46     }
47 };

 

posted @ 2014-03-22 15:48  flowerkzj  阅读(282)  评论(0编辑  收藏  举报