/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Heap {
vector<ListNode*> data_;
public:
void Push(ListNode* ele) {
data_.push_back(ele);
unsigned long i = data_.size() - 1;
while (i != 0 ) {
if (data_[(i-1)/2]->val > data_[i]->val ) {
swap(data_[(i-1)/2], data_[i]);
}
i = (i-1)/2;
}
};
ListNode* Pop() {
if(data_.empty()) return NULL;
ListNode* res = data_[0];
ListNode* tail = data_[data_.size() - 1];
data_.pop_back();
data_[0] = tail;
int i = 0;
while (2*i +2 < data_.size()) {
if (data_[2*i+1]->val < data_[i]->val && data_[2*i+1]->val <= data_[2*i+2]->val) {
swap(data_[i], data_[2*i+1]);
i = 2*i+1;
} else if(data_[2*i+2]->val < data_[i]->val && data_[2*i+2]->val <= data_[2*i+1]->val) {
swap(data_[i], data_[2*i+2]);
i = 2*i+2;
} else {
break;
}
}
if (2*i +2 == data_.size()) {
if (data_[2*i+1]->val < data_[i]->val) {
swap(data_[i], data_[2*i+1]);
}
}
return res;
}
bool Empty() {
return data_.empty();
}
void Dump() {
/*for (int i = 0; i < data_.size();i++){
cout << "," << data_[i]->val;
}
cout << endl;*/
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode * res = NULL;
ListNode * cur_list = NULL;
if (lists.empty()) {
return res;
}
Heap heap_;
for (int i = 0; i < lists.size(); ++i) {
if (lists[i]) {
heap_.Push(lists[i]);
}
ListNode * head = lists[i];
while (head != NULL) {
cout<< ","<<head->val;
head= head->next;
}
cout<< endl;
}
heap_.Dump();
res = heap_.Pop();
cur_list = res;
heap_.Dump();
while (!heap_.Empty()) {
if (cur_list->next != NULL) {
heap_.Push(cur_list->next);
heap_.Dump();
}
cur_list->next = heap_.Pop();
cur_list = cur_list->next;
heap_.Dump();
}
return res;
}
};
使用最小堆实现kmerge下的最小值求取。
最小堆维护的是当前所有的list的head。
最小堆在写的过程中,需要注意的地方:
1 索引i的父索引是(i-1)/2,不是i/2
2 在pop堆顶之后需要讲堆的最后一个元素放在堆顶,然后进行调整,调整的过程中,需要判定:
2.1 子左节电是不是比当前节点小,但是不小于子右节点
2.1 子右节电是不是比当前节点小,但是不小于子左节点
当只有两个条件都不满足的情况下,才能退出调整。
使用最小堆的kmerge算法的算法复杂度是nlogk的