原题描述
+
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
原题链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
思路解析
+
在面试的时候,面试官可能会先问你下面这道题。
然后再问你,如何合并k个有序链表。
挨个合并是绝对没有问题的,这样只需要k-1次合并就能完成。其实更好的方法是两两合并。比如说,先让1和k-1合并,再让2和k-2合并....如此一来,合并的次数就降到了log级别。思路确实简单,但实现的时候需要递归。下图展示了8个链表,在两两合并情况下的合并过程。
复杂度分析
+
C++参考代码
+
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(-1);
ListNode *p1 = l1, *p2 = l2, *q = head;
int val = 0;
while (p1 != NULL && p2 != NULL) {
if (p1->val <= p2->val) {
q->next = p1;
p1 = p1->next;
} else {
q->next = p2;
p2 = p2->next;
}
q = q->next;
}
q->next = p1 != NULL ? p1 : p2;
return head->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists, int begin, int end) {
if (begin > end) return NULL;
if (begin == end) return lists[begin];
int mid = (begin + end) / 2;
return mergeTwoLists(mergeKLists(lists, begin, mid), mergeKLists(lists, mid + 1, end));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return mergeKLists(lists, 0, lists.size() - 1);
}
};