1. 程式人生 > >合併K個已排序的連結串列。返回一個排序連結串列

合併K個已排序的連結串列。返回一個排序連結串列

本題源自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;
        }
    }