23.合并K个有序链表

合并k个有序链表

我们首先把k个链表的首元素都加入最小堆中,它们会自动排好序。
然后我们每次取出最小的那个元素加入我们最终结果的链表中,
然后把取出元素的 下一个元素 再加入堆中,下次仍从堆中取出最小的元素做相同的操作,
以此类推,直到堆中没有元素了,此时k个链表也合并为了一个链表,返回首节点即可,代码如下:
方法一,利用堆的性质

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        auto cmp = [](ListNode*& a, ListNode*& b) {
            return a->val > b->val;
        };
        priority_queue<ListNode*, vector<ListNode*>, decltype(cmp) > q(cmp);
        for (auto node : lists) {
            if (node) q.push(node);
        }
        ListNode *dummy = new ListNode(-1), *cur = dummy;
        while (!q.empty()) {
            auto t = q.top(); q.pop();
            cur->next = t;
            cur = cur->next;
            if (cur->next) q.push(cur->next);
        }
        return dummy->next;
    }
};
方法2
分治法, 归并排序,既然是有k个有序的链表,则不难想到归并
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()) return NULL; 
        return helper(lists, 0, (int)lists.size() - 1);//既然k个有序链表都是有序的,我们对他们归并排序
         
    }
    ListNode* helper(vector<ListNode*>& lists, int start, int end) { //先调用递归函数,将区间分割到最小  
        if (start == end) return lists[start]; //递归到只有一个的时候,直接返回该链表 
        int mid = start + (end - start) / 2;
        ListNode *left = helper(lists, start, mid);//向左半边递归 ,left为左边归并的结果 
        ListNode *right = helper(lists, mid + 1, end);//向右半边递归 ,right为右边归并的结果 
        return mergeTwoLists(left, right); //合并左右归并结果,返回合并后的有序链表 
    }
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { //合并两个有序链表 
        ListNode *dummy = new ListNode(-1);
        ListNode *t = dummy;
        ListNode *p,*q;
        p = l1;
        q = l2;
        while(p&&q)
        {
            if(p->val <= q->val)
            {
                t->next = p;
                p=p->next;
                t = t->next;
            }
            else
            {
                t->next = q;
                q = q->next;
                t = t->next;
            }
        }
        if(q)
        {
            t->next = q;
        }
        if(p)
        {
            t->next =p;
        }
        return dummy->next;
    }
}; 

 

posted @ 2020-08-27 12:06  King777  阅读(434)  评论(0)    收藏  举报