美文网首页算法提高之LeetCode刷题
【LeetCode每日一题】23. Merge k Sorted

【LeetCode每日一题】23. Merge k Sorted

作者: 七八音 | 来源:发表于2020-07-23 22:55 被阅读0次

    题目描述

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

    Example:

    Input:
    [
      1->4->5,
      1->3->4,
      2->6
    ]
    Output: 1->1->2->3->4->4->5->6
    

    合并k个有序单链表,然后返回这个新链表。分析时间复杂度、空间复杂度。

    题解

    暴力破解

    将链表转换成数组,然后将数组排序,最后根据数组中的顺序依次生成结果链表中的节点。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            if (lists.empty()) return nullptr;
            vector<int> arr;
            
            for (ListNode* list : lists){
                while (list){
                    arr.push_back(list->val);
                    list = list->next;
                }
            }
            sort(arr.begin(), arr.end());
            ListNode *first = new ListNode(-1), *node = first;
            
            for (int val : arr){
                node->next = new ListNode(val);
                node = node->next;
            }
            
            return first->next;
        }
    };
    

    时间复杂度:O(NlogN)

    空间复杂度:O(N).

    优先队列

    同时进行k个链表的合并,通过将每个链表的头结点放入优先队列中(同时完成了排序),弹出节点,将节点并入结果链表中,如果当前节点仍不为空,则将下一个节点压入优先队列中。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            auto cmp = [](ListNode* &l1, ListNode* &l2){
                return l1->val > l2->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 (t->next) q.push(t->next);
            }
            
            return dummy->next;
        }
    };
    

    时间复杂度:O(Nlogk)

    空间复杂度:O(N)新链表所用空间;O(k)优先队列所占空间。

    两两合并

    类似于分治法,不断进行两两合并,直到只剩最后一个链表,这个链表就为最终的结果链表。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            if (lists.empty()) return nullptr;
            
            int size = lists.size();
            
            while (size > 1){
                int k = (size + 1)/2;
                for (int i=0; i< size/2; i++)
                    lists[i] = merge(lists[i], lists[i+k]);
                size = k;
            }
            
            return lists[0];
        }
    private:
        ListNode* merge(ListNode *l1, ListNode *l2){
            ListNode *first = new ListNode(-1);
            ListNode *node = first;
            
            while(l1 && l2){
                if (l1->val < l2->val){
                    node->next = l1;
                    l1 = l1->next;
                }
                else{
                    node->next = l2;
                    l2 = l2->next;
                }
                node = node->next;
            }
            if (l1) node->next = l1;
            if (l2) node->next = l2;
            
            return first->next;
        }
    };
    

    时间复杂度:O(Nlogk)

    空间复杂度:O(1)

    References

    https://leetcode.com/problems/merge-k-sorted-lists/solution/


    欢迎关注公众号,一起学习

    相关文章

      网友评论

        本文标题:【LeetCode每日一题】23. Merge k Sorted

        本文链接:https://www.haomeiwen.com/subject/hzvklktx.html