首页 > 代码库 > LeetCode[Linked List]: Merge k Sorted Lists

LeetCode[Linked List]: Merge k Sorted Lists

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

一开始我没有采用分治法,解题思路是:首先比较每条链表的第一个元素,找出最小的那个,插入新链表并从原链表删除,如此反复直至所有的链表都为空链表。基于这个愚蠢的解题思路,我的C++代码实现如下:

    ListNode *mergeKLists(vector<ListNode *> &lists) {
        ListNode *dummyHead = new ListNode(0);
        ListNode *tail = dummyHead;

        int leftLists = lists.size();
        for (int i = 0; i < leftLists; i++)
            if (!lists[i])
                lists[i--] = lists[--leftLists];

        while (leftLists) {
            int curMinIdx = 0;
            for (int i = 1; i < leftLists; i++)
                if (lists[i]->val < lists[curMinIdx]->val)
                    curMinIdx = i;

            tail->next = lists[curMinIdx];
            tail = lists[curMinIdx];
            lists[curMinIdx] = lists[curMinIdx]->next ? lists[curMinIdx]->next : lists[--leftLists];
        }

        return dummyHead->next;
    }

毫无疑问,我得到了“Time Limit Exceeded”,这种解法对于每一个元素都查找了所有的链表,这个复杂度是非常高的。以后一定要避免这样的解法!

然后,我采用了分治法,每次合并两条链表,采用堆排序算法来实现:

class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        int leftLists = lists.size();
        while (leftLists > 1) {
            for (int i = 0; i < (leftLists >> 1); ++i)
                lists[i] = merge2Lists(lists[i], lists[leftLists - 1 - i]);
            leftLists = (leftLists + 1) >> 1;
        }

        return lists.empty() ? nullptr : lists[0];
    }

    ListNode *merge2Lists(ListNode *h1, ListNode *h2) {
        ListNode *dummyHead = new ListNode(0);
        ListNode *tail = dummyHead, *cur[2] = {h1, h2};
        while (cur[0] && cur[1]) {
            int idx = (cur[0]->val >= cur[1]->val);
            tail->next = cur[idx];
            tail = cur[idx];
            cur[idx] = cur[idx]->next;
        }

        if (cur[0]) tail->next = cur[0];
        if (cur[1]) tail->next = cur[1];

        return dummyHead->next;
    }
};

后者的时间性能表现如下图所示,可以看到这种做法在C++里面的时间性能并不好,希望以后发掘更好更快的算法。

技术分享

LeetCode[Linked List]: Merge k Sorted Lists