题目
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
分析
基本就是归并排序的思想,两两分治。不同点是归并排序使用的是线性表,且会开辟额外空间。但这里是链表,且不允许使用额外空间。
实现
/**
* 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.empty()) return NULL;
return merge(lists, 0, lists.size()-1);
}
private:
ListNode* merge(vector<ListNode*>& lists, int start, int end) {
if(end==start) return lists[start];
int mid = (start+end)/2;
ListNode* l1 = merge(lists, start, mid);
ListNode* l2 = merge(lists, mid+1, end);
if(l1==NULL) return l2;
if(l2==NULL) return l1;
return mergeTwo(l1, l2);
}
ListNode* mergeTwo(ListNode* l1, ListNode* l2){
ListNode dummy(-1);
ListNode* pa=&dummy;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val){
pa->next = l1;
l1 = l1->next;
pa = pa->next;
}
else{
pa->next = l2;
l2 = l2->next;
pa = pa->next;
}
}
pa->next = l1!=NULL ? l1: l2;
return dummy.next;
}
};
思考
写的mergeTwo函数的时候看了下之前的21. Merge Two Sorted Lists的代码,实在太丑了。
对改进的地方总结下:
- 使用dummy节点,统一初始节点的处理方式
- 两个链表在排完一个之后,直接将另一个剩下的部分链接到末尾即可,不需要像归并排序那样全部复制。
网友评论