• Merge k Sorted Lists


    /*Merge k sorted linked lists and return it as one sorted list.
     Analyze and describe its complexity. */
    #include <iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<queue>
    #include<vector>
    using namespace std;
    
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL) {}
    };
    //struct cmp:public binary_function<ListNode*,ListNode*,bool>
    class cmp//class is more simple than struct
    {
    public:
        bool operator()(ListNode* la,ListNode* lb)
        {
            if(!la||!lb)
                return !la;
            return la->val>lb->val;
        }
    };
    class Solution2
    {
        ListNode* mergeKLists(vector<ListNode*>& lists)
        {
            //Time LimitExceeded
            if(lists.empty())
                return NULL;
            ListNode*head=NULL,*pos=NULL;
            do
            {
                make_heap(lists.begin(),lists.end(),cmp());
                pop_heap(lists.begin(),lists.end(),cmp());
                ListNode* last=lists.back();
                if(head==NULL)
                {
                    head=last;
                    pos=last;
                }
                else
                {
                    pos->next=last;
                    pos=last;
                }
                if(last==NULL)
                    break;
                lists.pop_back();
                lists.push_back(last->next);
            }
            while(1);
            return head;
        }
    };
    class Solution1
    {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists)
        {
            for(vector<ListNode*>::iterator it=lists.begin(); it!=lists.end();)
                if(*it==NULL)
                    it=lists.erase(it);
                else
                    it++;
            if(lists.empty())
                return NULL;
            ListNode*head=NULL,*pos=NULL,*last=NULL;
            make_heap(lists.begin(),lists.end(),cmp());
            do
            {
                pop_heap(lists.begin(),lists.end(),cmp());
                last=lists.back();
                if(head==NULL)
                {
                    head=last;
                    pos=last;
                }
                else
                {
                    pos->next=last;
                    pos=last;
                }
                lists.erase(lists.end()-1);
                if(last->next)
                {
                    lists.push_back(last->next);
                    push_heap(lists.begin(),lists.end(),cmp());
                }
            }
            while(lists.size());
            if(pos!=NULL)
                pos->next=NULL;
            return head;
        }
    };
    class Solution
    {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists)
        {
            vector<int>::size_type i;
            priority_queue<ListNode*,vector<ListNode*>,cmp>Q;
            for(i=0; i<lists.size(); i++)
            {
                if(lists[i]!=NULL)
                    Q.push(lists[i]);
            }
            ListNode*head=NULL,*pos=NULL,*pre=NULL;
            while(!Q.empty())
            {
                pre=Q.top();
                Q.pop();
                if(head==NULL)
                {
                    head=pre;
                    pos=pre;
                }
                else
                {
                    pos->next=pre;
                    pos=pre;
                }
                if(pre->next)
                    Q.push(pre->next);
            }
            return head;
        }
    };
    int main()
    {
        ListNode* ls[8];
        for(int i=0; i<5; i++)
            ls[i] =new ListNode(4-i);
        ls[5]=new ListNode(3);
        ls[5]->next=NULL;
        ls[6]=NULL;
        ls[7]=NULL;
        vector<ListNode*> lists(ls,ls+8);
        //Solution s;
        Solution1 s;
        ListNode*head=s.mergeKLists(lists);
        while(head)
        {
            cout<<head->val<<endl;
            head=head->next;
        }
        return 0;
    }

    首先用常规的合并方法肯定是会超时的。我们现在使用堆排序来做。

    Solution2和Solution1最大的区别就是make_heap放在了循环里面,这也是我参考网上其他网友的答案。但是Solution2超时,而Solution1能AC。其实道理很简单,我们知道k个元素建堆的时间复杂度是O(k),而调整堆(pop_head和push_head)的复杂度是O(lgk)。若是把make_heap放在循环里面,那么每次都会重新建堆。而其实我们只是对换了堆顶元素和最后一个元素,所以仅仅需要调整堆就可以。综述,Solution2因为一个简单的操作把总的时间复杂度变为了O(nk),而Solution1的时间复杂度仅仅是O(nlgk)。

    Solution其实就是运用了priority_queue,而优先队列本来就是使用了堆的相关操作,所以和Solution1的本质相同。

  • 相关阅读:
    java Thread之ThreadLocal(线程局部变量)
    java设计模式之接口隔离原则(ISP)
    java设计模式之开放关闭原则(OCP)
    java设计模式之迪米特法则(LoD)
    java设计模式之单一职责原则(SRP)
    android点滴(25)之 originalpackage
    VC 注册表操作
    java设计模式之依赖倒置原则(DIP)
    DFT 离散傅里叶变换 与 补零运算
    序列循环移位
  • 原文地址:https://www.cnblogs.com/heqinghui/p/4840692.html
Copyright © 2020-2023  润新知