Merge k Sorted Lists
题目描述
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
实验思路
- 因为是已经是排好序的数组,所以没必要遍历一遍生成一个新的数组再进行递归排序,这样不仅浪费内存,也浪费时间。
- 所以采用分治的思想,把这个vector中的lists分为两半,再进行排序。
- 递归步骤2。
- 合并并排序。
## 代码展示
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* mergeLists(ListNode* left, ListNode *right){
//如果左边的链表为空,则返回右边的链表
if(!left){
return right;
}
//如果右边的链表为空,则返回左边的链表
if(!right){
return left;
}
//变量ptr用于记录最后返回的合并后的链表的头
ListNode* ptr = NULL;
//变量pptr用于整合两个链表
ListNode** pptr = &ptr;
while(left || right){
//如果左边的链表不为空且大于右边的链表,则把该节点从原链表中取出,将NULL赋值给该节点的next指针其实就相当于把它从原来的链中“打断”
if((left && !right) || (left && (left->val < right->val))){
*pptr = left;
ListNode* temp = left->next;
left->next = NULL;
ptr = &((*pptr)->next);
left = temp;
}else{
*pptr = right;
ListNode* temp = right->next;
right->next = NULL;
pptr = &((*pptr)->next);
right = temp;
}
}
return ptr;
}
//将链表数组递归分为左右两半
ListNode* mergeK(const vector<ListNode*>::iterator begin, const vector<ListNode*>::iterator end){
if(begin == end){
return nullptr;
}
if(distance(begin, end) == 1){
return *begin;
}
int mid = distance(begin, end)/2;
ListNode* left = mergeK(begin, begin + mid);
ListNode* right = mergeK(begin + mid, end);
return mergeLists(left, right);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
auto begin = lists.begin();
auto end = lists.end();
return mergeK(begin, end);
}
};
实验总结
pptr的使用,减少了内存的浪费,还是用原来的链表节点已分配的内存。