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 };