- 题目地址及大意
- 优先队列方法
- 使用STL模板类构建优先队列和堆
题目地址及大意
题目23. Merge k Sorted Lists大意如下:
给定 k 个有序数列,都按照从小到大的顺序排列,将这 k 个有序数列融合为1个有序数列
优先队列方法
因为 k 个数列都是有序的,因此我们在将这 k 个数列中的数一个一个地插入最终融合的数列时,我们每次都是插入当前 k 个序列头结点中的最小值。使用传统的遍历方法,时间复杂度为 O(k), 而使用堆排序的方法,可以将时间复杂度缩减为 O(log k),因此我们采用堆排序的方法。
首先将 k 个序列的头结点组成最小堆,而后执行 deleteMin 操作,再在最小堆中插入被删除的结点后面的元素,直至堆为空。程序如下:
#include<iostream>
#include<vector>
#include<queue>
#include<functional>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
vector<ListNode*>::iterator iter = lists.begin();
priority_queue<ListNode*, vector<ListNode*>, comp> q;
for(;iter!=lists.end();iter++){
if((*iter) != NULL)
q.push(*iter);
}
struct ListNode* list;
if(q.size()==0)
return NULL;
list = q.top();
struct ListNode* tail;
tail = list; //using list to save the result;
struct ListNode* now;
now = q.top();
if(now->next != NULL){
now = now->next;
q.push(now);
}
q.pop();
while(!q.empty()){
now = q.top();
tail->next = now;
tail = tail->next;
q.pop();
if(now->next != NULL){
now = now->next;
q.push(now);
}
}
return list;
}
struct comp{
bool operator()(const ListNode* l1, const ListNode* l2){
return l1->val > l2->val;
}
};
};
int main()
{
struct ListNode* list1;
struct ListNode* list2;
struct ListNode* list3;
struct ListNode* list4;
struct ListNode* temp;
list1 = &ListNode(1);
temp = list1;
temp->next = &ListNode(7);
temp = temp->next;
temp->next = &ListNode(8);
temp = temp->next;
temp->next = &ListNode(10);
list2 = &ListNode(2);
list2->next = &ListNode(5);
temp = list2->next;
temp->next = &ListNode(6);
temp = temp->next;
temp->next = &ListNode(9);
list3 = &ListNode(4);
list3->next = &ListNode(11);
temp = list3->next;
temp->next = &ListNode(32);
temp = temp->next;
temp->next = &ListNode(40);
list4 = &ListNode(3);
list4->next = &ListNode(13);
temp = list4->next;
temp->next = &ListNode(17);
temp = temp->next;
temp->next = &ListNode(19);
vector<ListNode*> lists;
lists.push_back(list1);
lists.push_back(list2);
lists.push_back(list3);
lists.push_back(list4);
class Solution t;
ListNode* result;
result = t.mergeKLists(lists);
while(result != NULL){
cout<<result->val<<" ";
result = result->next;
}
system("pause");
return 0;
}
程序比较繁琐,可以设置一个哑结点作为头结点,进行简化。
使用STL模板类构建优先队列和堆
我个人认为使用优先队列比使用堆更为简便,后续待更新