LeetCode 23. 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
题目理解:
这套题是将Merge 2 sorted lists 的升级版,我的思路就是每次取所有链表中最小的一个元素,然后组成新的链表,我就直接做了,然后时间只击败了1.35%的人。。。
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* head = new ListNode(0);
ListNode* start = head;
while(1){
int min=INT_MAX;
int tmp=-1;
bool flag = true;
for(int i=0;i<lists.size();i++){
if(lists[i]!=NULL && lists[i]->val < min){
min = lists[i]->val;
tmp = i;
}
flag = flag && (lists[i]==NULL);//所有全空才停止
}
if(flag) break;
head->next = new ListNode(min);
head = head->next;
lists[tmp] = lists[tmp]->next;
}
return start->next;
}
};
然后学习优秀代码,发现这种每次挑选最小的元素的思想可以用小顶堆的数据结构承载实现,消耗的时间很少,于是查询相关知识。
堆在C++里面用优先队列来实现
在优先队列中,没有 front() 函数与 back() 函数,而只能通过 top() 函数来访问队首元素(也可称为堆顶元素),也就是优先级最高的元素。
//下面两种优先队列的定义是等价的
priority_queue<int> q;
priority_queue<int,vector<int>,less<int> >;//后面有一个空格
其中第二个参数( vector ),是来承载底层数据结构堆的容器,第三个参数( less ),则是一个比较类,less 表示数字大的优先级高,而 greater 表示数字小的优先级高。
对结构体的优先级设置要进行内部重载,或者再写个结构体在这个结构体内部进行重载bool operator()。
然后再模仿着写了代码:
struct cmp{
bool operator()(ListNode *a,ListNode *b){//这里operator后面的()不能去掉
return a->val > b->val;
}
};
//因为无法对原结构体进行修改,所以就采用了在外面再声明一个结构体的方法。
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* head = new ListNode(0);
ListNode* start = head;
priority_queue<ListNode*,vector<ListNode*>,cmp> heap;
for(int i=0;i<lists.size();i++){
if(lists[i]!=NULL) heap.push(lists[i]);
}
//堆里面存储的永远是几个ListNode*,然后由这些指针继续往后找
while(!heap.empty()){
ListNode* s = heap.top();//这里的s是返回的对应lists的下标。
heap.pop();
if(s->next!=NULL) heap.push(s->next);
head->next = s;
head=head->next;
}
return start->next;
}
};
加油,需要继续努力!