Leetcode Merge k Sorted Lists

OpenSoucre發表於2014-07-01

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

合併k個排序列表

解題思路是:

取出 k個元素進行堆排序,每次取出最小的元素,插入連結串列中即可

注意本題利用了c++得優先權佇列,優先權佇列底層是用堆實現的

注意本題中一個特殊的測試用例是[{}]

注意vector為空時表示為[],而不是[{}],而後者是大小為1的vector,其中元素是空指標

放入優先權佇列時進行判斷是否為空

放入優先權佇列的元素是ListNode *, 而不是int,主要是保持原有連結串列的地址,避免地址失效,而且放入int話,之後又重新new ListNode(int)開銷還是比較大的.

對放入優先權佇列中得ListNode*要定義一個比較函式物件,如果不定義的話,比較的是地址大小

class Solution {
public:
    struct cmp{
        bool operator()(const ListNode* a, const ListNode* b) const{
            return a->val > b->val;
        }
    };
    
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.empty()) return NULL;
        priority_queue<ListNode*,vector<ListNode*>,cmp> pq;
        ListNode *head = new ListNode(0), *pre = head;
        for(int i = 0 ; i < lists.size(); ++ i){
            if(lists[i]) pq.push(lists[i]);
        }
        while(!pq.empty()){
            ListNode* node = pq.top(); pq.pop();
            if(node->next) pq.push(node->next);
            pre->next = node;
            pre = node;
        }
        pre->next = NULL;
        return head->next;
    }
};

 第二種方法是二分的方法,每次取兩個ListNode * 進行合併

程式中運用了佇列,每次從佇列中取出兩個元素然後合併,將合併後的元素又放入佇列,直到佇列只剩小一個元素為止即可

class Solution {
public:
    ListNode *mergeLists(ListNode* p,ListNode* q){
        ListNode* head = new ListNode(0),*pre = head;
        while(p && q){
            if(p->val < q ->val){
                ListNode *tmp = p->next;
                p->next = pre->next;
                pre->next = p;
                pre = p;
                p = tmp;
            }else{
                ListNode *tmp = q->next;
                q->next = pre->next;
                pre->next = q;
                pre = q;
                q = tmp;
            }
        }
        pre->next = NULL;
        if(p) pre->next = p;
        if(q) pre->next = q; 
        return head->next;
    }

    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.empty()) return NULL;
        queue<ListNode *> que;
        for(int i = 0 ; i < lists.size(); ++ i){
            if(lists[i]) que.push(lists[i]);
        }
        while(que.size()>1){
            ListNode* p = que.front();que.pop();
            ListNode* q = que.front();que.pop();
            que.push(mergeLists(p,q));
        }
        return que.front();
    }
};

 

相關文章