本题源自LeetCode
-------------------------------------------------------------
思路1 : 优先队列
1 遍历所有的链表,将首节点放入优先队列。
2 取出优先队列的头,即最小的节点。链接到新链表的尾部。
3 如果队列首节点的链表不空,就将下一个节点入队列。依次循环1-3步。
代码:
struct compare{
bool operator()(const ListNode* a,const ListNode* b){
return a->val > b->val;
}
};
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<ListNode*,vector<ListNode*>,compare> que; //优先队列
for(auto node:lists){
if(node)
que.push(node);
}
if(que.empty())
return NULL;
ListNode* root=new ListNode(0);
root->next=NULL;
ListNode* pre=root;
while(que.size()){
ListNode* p=que.top(); //取队列头部,最小的那个节点
que.pop();
pre->next=p;
pre=p;
if(pre->next){ //取节点那个链表不空,向后遍历
que.push(pre->next);
}
}
return root->next;
}
思路 2 : 最小堆
1 和上面一样遍历 各链表首节点 然后建堆
2 取出堆顶点,然后调整堆
3 如果当前最小节点的链表不空,则下一个节点入堆,调整堆,循环
代码:
struct compare{
bool operator()(const ListNode* a,const ListNode* b){
return a->val > b->val;
}
};
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
vector<ListNode*> vec; //最小堆
for(auto node:lists){
if(node)
vec.push_back(node);
}
ListNode* root=new ListNode(0);
root->next=NULL;
ListNode* pre=root;
make_heap(vec.begin(),vec.end(),compare()); //建堆
while(vec.size()){
pre->next=vec[0];
pop_heap(vec.begin(),vec.end(),compare()); //将第一个节点与最后一个作交换
vec.pop_back(); //删除最后一个节点
pre=pre->next;
if(pre->next){
vec.push_back(pre->next);
push_heap(vec.begin(),vec.end(),compare());
}
}
return root->next;
}
思路3
归并排序。先两两合并然后在合并
代码:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.size()==0)
return NULL;
while(lists.size()>1){
lists.push_back(mergeList(lists[0],lists[1]));
lists.erase(lists.begin());
lists.erase(lists.begin());
}
return lists.front();
}
ListNode* mergeList(ListNode* l1,ListNode* l2){
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
if(l1->val<l2->val){
l1->next=mergeList(l1->next,l2);
return l1;
}else{
l2->next=mergeList(l1,l2->next);
return l2;
}
}