怎么找几个序列的最小值?
如果用while循环来做,假设所有序列的总长度加起来是n。每加一个元素就要循环k次(k个指针),总体的复杂度O(nk)
用堆来寻找最小值,用堆来维护k个指针。每次取出堆中最小值的复杂度
O
(
1
)
O(1)
O(1)。把指针往后移动,然后插入堆中,复杂度为
O
(
l
o
g
k
)
O(logk)
O(logk)。总的复杂度
O
(
n
l
o
g
k
)
O(nlogk)
O(nlogk)
c++的堆用优先队列表示。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
//Cmp(a,b)
//priority_queue优先级的定义:两个数a,b,如果返回(本代码指Cmp(a,b))true,则a的优先级小于b的优先级
//STL priority_queue 是默认大根堆,比较符号默认是<
struct Cmp{
bool operator() (ListNode* a, ListNode* b){
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
//priority_queue<Type, Container, Functional>
//Type为数据类型
//Container为保存数据的容器
//Functioanl为元素比较方式
priority_queue<ListNode*, vector<ListNode*>, Cmp> heap;
auto dummy = new ListNode(-1), tail = dummy;
for(auto l : lists) if(l) heap.push(l);
while(heap.size()){
auto t = heap.top();
heap.pop();
tail = tail->next = t;
if(t->next) heap.push(t->next);
}
return dummy->next;
}
};
补充:
c++的优先队列不支持删除,可以用bool数组或set标记一下。