[Leetcode] 23. Merge k Sorted Lists 解题报告

来源:互联网 发布:秃用一体握把淘宝 编辑:程序博客网 时间:2024/04/30 23:03

题目

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

思路

        可以认为是Leetcode 21 Merge Two Sorted List的推广,其思路还是大同小异的,即每次从k个链表中找出头结点最小的那一个,加入到合并后的单链表末尾。假设k个列表中的节点个数总和 为m,那么朴素解法的时间复杂度为O(m*k)。但实际上在这里我们没有利用k个链表中的头结点的大小的相对稳定性,即每次当我们取出一个最小的头结点之后,其余头结点之间的相对大小还是稳定的,我们只需要更新新加入的头结点(如果有的话)到合适的位置,即可在O(1)的时间获得下一个最小的头结点。

        事实上,有一类数据结构非常适这类应用场景:堆!堆的构建时间复杂度是O(k),取得最大最小值的时间复杂度为O(1),添加和删除元素的时间复杂度均为O(logk),简直就是为本题目量身定做的!在STL中,采用vector实现的heap以及priority_queue均可实现这一目标。这样,该算法的时间复杂度就降为O(m*logk),空间复杂度为O(k)。

代码

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) {        vector<ListNode*> vec;        for(int i = 0; i < lists.size(); ++i)        {            if(lists[i]  != NULL)                vec.push_back(lists[i]);        }        ListNode pre_head(0);        ListNode* node = &pre_head;        make_heap(vec.begin(), vec.end(), ListNodeComp);        while(vec.size() > 0)        {            ListNode* front = vec[0];            pop_heap(vec.begin(), vec.end(), ListNodeComp);            vec.pop_back();            node->next = front;            node = node->next;            if(front->next != NULL)            {                vec.push_back(front->next);                push_heap(vec.begin(), vec.end(), ListNodeComp);            }        }        return pre_head.next;    }private:    struct ListNodeCompare    {        bool operator() (ListNode* l1, ListNode* l2) const        {            return l1->val > l2->val;        }    } ListNodeComp;};

2、优先级队列版本:

/** * 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* a, ListNode* b) { return a->val > b->val; };          priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> que(cmp);          ListNode pre_head(0), *p = &pre_head;          for(auto val: lists)             if(val) que.push(val);          while(!que.empty())          {              auto val = que.top();              p->next = val, p = p->next;              que.pop();              if(val->next)                 que.push(val->next);          }          return pre_head.next;      }};

0 0