题目
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
算法思路
输入:k个从小到大排序好的链表
输出:合并k个链表后的结果链表
这道题的解法思路有很多,最直接的当然是把链表的所有数据遍历并记录在一个数组中,然后使用一些基本的排序算法例如冒泡排序,快速排序之类的。但这样的效率很低,也没有很好的利用了链表这个数据结构。
我们可以参照一下课堂上的分治的思想,把一个大问题转化成多个相同性质的小问题。为方便理解思路,我引用了标准解法里面的图
现在问题变成了合并两个链表。假设初始k个链表的规模都相近,则上图的合并顺序是最优的,因为它保持了每一轮合并时操作的链表规模尽可能的小。
而合并两个链表的思路也很直接,不断比较两个链表的表头元素,取较小的元素到新的链表,直到其中某个链表元素取尽。
C++代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0)
{
return NULL;
}
vector<ListNode*> nextlists;
while(lists.size() != 1) {
nextlists.clear();
for(int i = 0; i < lists.size()/2; i++){
nextlists.push_back(merge(lists[2*i], lists[2*i+1]));
}
if (lists.size() % 2 == 1)
{
nextlists.push_back(lists[lists.size()-1]);
}
lists.swap(nextlists);
}
return lists[0];
}
//合并两个有序链表成一个有序链表
ListNode* merge(ListNode *first, ListNode *second) {
ListNode *head = new ListNode(0);
ListNode *p = head;
while(first != NULL && second != NULL){
if (first->val < second->val)
{
p->next = first;
first = first->next;
}
else{
p->next = second;
second = second->next;
}
p = p->next;
}
if (first != NULL)
{
p->next = first;
}
if (second != NULL)
{
p->next = second;
}
p = head->next;
delete head;
return p;
}
};