23. Merge k Sorted Lists

  • 题目地址及大意
  • 优先队列方法
  • 使用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模板类构建优先队列和堆

我个人认为使用优先队列比使用堆更为简便,后续待更新


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值