leetcode 23. 合并K个排序链表

问题描述

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

代码1(逐一比较)

/**
 * 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) {
        int n = lists.size();
        if(n == 0)return NULL;
        ListNode* ans = new ListNode(0);
        ListNode* a = ans;
        int i,minindex,minnum;
        while(checknull(lists,n))
        {
            minnum = INT_MAX;
            for(i = 0; i < n; i++)
            {
                if(lists[i] != NULL && minnum > lists[i]->val)
                {
                    minnum = lists[i]->val;
                    minindex = i;
                }                
            }
            a->next = lists[minindex];
            lists[minindex] = lists[minindex]->next;
            a = a->next;
        }
        a = ans->next;
        delete ans;
        return a;
    }
    bool checknull(vector<ListNode*>& lists,int n)
    {
        int i;
        for(i = 0; i < n; i++)
        {
            if(lists[i])return true;
        }
        return false;
    }
};

结果有点难以启齿:

执行用时 :464 ms, 在所有 cpp 提交中击败了12.25%的用户
内存消耗 :10.8 MB, 在所有 cpp 提交中击败了96.16%的用户

时间复杂度为O(nk),n为链表的个数(内层循环比较),k是节点总数目(最外层循环),但空间复杂度为O(1)。

代码2(优先队列)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    struct cmp
    {
        bool operator()(ListNode* &l1,ListNode* &l2)
        {
            return l1->val >l2->val;
        }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        int n = lists.size();
        if(n == 0)return NULL;
        ListNode* ans = new ListNode(0);
        ListNode* a = ans,*b;
        priority_queue<ListNode*,vector<ListNode*>,cmp> pq;
        for(int i = 0; i < n; i++)
        {
            if(lists[i])pq.push(lists[i]);
        }
        while(!pq.empty())
        {
            b = pq.top();
            pq.pop();
            a->next = b;
            b = b->next;
            a = a->next;
            if(b)pq.push(b);
        }
        a = ans->next;
        delete ans;
        return a;
    }
};

结果:

执行用时 :36 ms, 在所有 cpp 提交中击败了74.37%的用户
内存消耗 :11 MB, 在所有 cpp 提交中击败了89.84%的用户

因为代码一外部每循环一次内部都要比较,但比较完之后的结果下一步没有利用,优先队列则利用了这一信息,从而降低了时间复杂度。时间复杂度为:O(klog(n)),空间复杂度为O(n).其中关于priority_queue的用法参考这个网址.

代码3(分治)

结果

相似题型

posted @ 2020-03-04 20:37  曲径通霄  阅读(140)  评论(0编辑  收藏  举报