将k个列表排序汇合
输入:链表节点指针的向量
输出:链表节点的指针
思路:
假设有k个链表,每个链表的平均长度为l
1.连续merge2
2l+3l+4l+…+kl = k*k*l/2
2.直接mergek
K*K*l
好像也差不多。
那就写个2merge试试吧
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode*total = NULL;
for(ListNode* node : lists){
total = mergeTwoLists(node,total);
}
return total;
}
居然还没超时,还可以
执行用时 : 292 ms, 在Merge k Sorted Lists的C++提交中击败了16.59% 的用户
内存消耗 : 11.7 MB, 在Merge k Sorted Lists的C++提交中击败了0.81% 的用户
顺便一提,使用分治的时间复杂度和一个一个2merge的时间复杂度相同,起不到什么好作用。
那么该看正确的解法了:
基于堆排序的k路合并算法:
class Solution {
public:
class priority{
public:
bool operator () (ListNode* a, ListNode* b){
if(a == NULL)
return false;
else if(b == NULL)
return true;
else
return a->val>b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.empty())
return NULL;
priority_queue<ListNode*, vector<ListNode*>, priority> help;
ListNode* ret_val = new ListNode(0);
auto temp_node = ret_val;
for(auto i:lists)
help.push(i);
while(!help.empty()){
auto temp = help.top();
help.pop();
if(temp != NULL){
temp_node->next = temp;
temp_node = temp_node->next;
help.push(temp->next);
}
}
return ret_val->next;
}
};
执行用时 : 84 ms, 在Merge k Sorted Lists的C++提交中击败了35.76% 的用户
内存消耗 : 11.9 MB, 在Merge k Sorted Lists的C++提交中击败了0.81% 的用户
利用ret_val当哨兵节点,然后利用队列,每次取出队列最前面的那一个的当前值,然后存入,然后队列进行重新排序,直到将k个链表都归并完成。这个方法的重点是要写一个完善的比较函数,然后将每个链表的表头指针存入优先级队列,然后根据优先级队列的性质获取当前k路里面的最小值。
需要注意的就是优先级队列的声明和使用
看到了一个暴力解法很有意思:就是将所有的链表直接合并,然后进行链表排序。。。时间复杂度就是排序的时间复杂度,K*L*K*L 应该是最高的时间复杂度了。