23. Merge k Sorted Lists

来源:互联网 发布:充值卡怎么冲淘宝 编辑:程序博客网 时间:2024/05/21 20:28

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

这是一道不难,却很值得思考的题目。包含了很多常见的算法思想。

方法一:
直接将所有链表里的数拷贝到数组里,对数组排序,然后生成新的链表。
时间复杂度主要再排序上,O(N*logN)。空间复杂度O(N). 代码略。

方法二:
方法一完全没有利用sorted lists的先验,这里完全可以减少排序过程中的比较。将比较缩小到K个链表的起始位,每次确定一个最小的加入新生成的链表。并将该指针往后移一位。时间复杂度O(KN). 空间复杂度如果是新建链表的话就是O(N), 如果是改变原来的connection的话,也就是in place, 就是O(1)。
代码略。

方法三:
方法二完全可以更优化一点,因为每次对K个数排序之后,我们只用了其中最小的一个,剩下的K-1个也是处于有序状态,没有必要再下一轮排序中重复对他们进行排序操作。所以这里可以用一个priority_queue来存储这些信息。代码如下:

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class compGreater {public:    bool operator() (const pair<int, ListNode*>& a, const pair<int, ListNode*>& b) {        return a.first > b.first;    }};class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {        ListNode* head = new ListNode(0);        ListNode* pnow = head;        priority_queue<pair<int, ListNode*>, vector<pair<int, ListNode*>>, compGreater> pq;        for (auto l : lists) {            if (l) pq.push({l->val, l});        }        while (!pq.empty()) {            int topval = pq.top().first;            ListNode* toppointer = pq.top().second;            pq.pop();            pnow->next = new ListNode(topval);            pnow = pnow->next;            if (toppointer->next) pq.push({toppointer->next->val, toppointer->next});        }        return head->next;    }};

方法四:
还有以一种基本方法是,可以逐一merge相应的链表。这里如果是merge两个有序链表的话,时间复杂度是O(m + n), m and n是两个各自的长度。所以我们来看整体的时间复杂度应该是:
K1i=1(iNK)+NK=O(KN)
空间复杂度取决于是否in place 操作。

方法五:
对方法四进行优化,逐一merge可以改成两两merge,这样相当于用divide and conquer来处理,复杂度降低为O(NlogK).
代码为:

class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {        queue<ListNode*> q;        for (auto l : lists) {            q.push(l);        }        while (q.size() > 1) {            ListNode* head = new ListNode(0);            ListNode* pnow = head;            ListNode* p1 = q.front();            q.pop();            ListNode* p2 = q.front();            q.pop();            while (p1 && p2) {                if (p1->val < p2->val) {                    pnow->next = p1;                    p1 = p1->next;                    pnow = pnow->next;                    pnow->next = NULL;                }                else {                    pnow->next = p2;                    p2 = p2->next;                    pnow = pnow->next;                    pnow->next = NULL;                }            }            while (p1) {                pnow->next = new ListNode(p1->val);                p1 = p1->next;                pnow = pnow->next;            }            while (p2) {                pnow->next = new ListNode(p2->val);                p2 = p2->next;                pnow = pnow->next;            }            q.push(head->next);        }        while (!q.empty()) return q.front();        return NULL;    }};
原创粉丝点击