题目:题目链接
题意:给出k个有序链表,返回一个合并后的有序链表。
思路:显而易见,每次遍历这个k个链表的表头,哪个最小就加入答案链表即可得到正确结果,但是这样做复杂度是爆炸的,对k个链表表头遍历一遍智能解决一个结点的排序问题,效率低下。
我们可以想到数据结构课程上学到的两个有序链表合并的问题,只需要O(n)的复杂度即可完成,且空间开销极小,只需要一个记录答案的头结点即可,那么这个问题能不能转化成简单的两个有序链表合并的问题呢,答案是可以的,参考归并排序,我们用二分的思想可以轻易的解决这一问题。
ac代码:
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 return divideLists(lists, 0, lists.size() - 1);
13 }
14
15
16 ListNode* divideLists(vector<ListNode*>& lists, int st, int ed) {
17 if(st == ed) return lists[st];
18 if(st > ed) return NULL;
19
20 ListNode* l = divideLists(lists, st, (st + ed) / 2);
21 ListNode* r = divideLists(lists, (st + ed) / 2 + 1, ed);
22
23 ListNode ans(0);
24 ListNode *tmp = &ans;
25 while(l && r) {
26 if(l->val < r->val) {
27 tmp->next = l;
28 l = l->next;
29 }
30 else {
31 tmp->next = r;
32 r = r->next;
33 }
34 tmp = tmp->next;
35 }
36
37 if(l) tmp->next = l;
38 else tmp->next = r;
39
40
41 return ans.next;
42
43 }
44 };