23. Merge k Sorted Lists 合并 K 个有序列表

题目链接
tag:

  • Hard;
  • Divide and Conquer;

question
  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个有序链表,最终合并出来的结果也必须是有序的,之前有道 Merge Two Sorted Lists,是混合插入两个有序链表。这道题增加了难度,变成合并k个有序链表了,但是不管合并几个,基本还是要两两合并。那么我们首先考虑的方法是能不能利用之前那道题的解法来解答此题。答案是肯定的,但是需要修改,怎么修改呢,最先想到的就是两两合并,就是前两个先合并,合并好了再跟第三个,然后第四个直到第k个。这样的思路是对的,但是效率不高,没法通过OJ,所以我们只能换一种思路,这里就需要用到分治法 Divide and Conquer Approach。简单来说就是不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并0和3,1和4,2和5。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了。代码中的k是通过 (n+1)/2 计算的,这里为啥要加1呢,这是为了当n为奇数的时候,k能始终从后半段开始,比如当n=5时,那么此时k=3,则0和3合并,1和4合并,最中间的2空出来。当n是偶数的时候,加1也不会有影响,比如当n=4时,此时k=2,那么0和2合并,1和3合并,完美解决问题,参见代码如下:

/**
 * 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) {
        if (lists.empty()) return NULL;
        int n = lists.size();
        while (n > 1) {
            int k = (n + 1) / 2;
            for (int i=0; i<n/2; ++i)
                lists[i] = mergeTwoLists(lists[i], lists[i+k]);
            n = k;
        }
        return lists[0];
    }

    // 合并两个链表
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *dummy = new ListNode(-1), *cur = dummy;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                cur->next = l1;
                l1 = l1->next;
            }
            else {
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;
        }
        if (l1) cur->next = l1;
        if (l2) cur->next = l2;
        return dummy->next;
    }
};

相似题目:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 睡意朦胧,眼皮惺忪,很想睡,这一天过得没什么波澜,想起明天要上班也没什么不爽,只是生存的问题再次困扰了我,穷鬼又找...
    思倍思阅读 137评论 0 0
  • 那一朵朵云的白, 即是我在蓝天上写下的诗句, 诉说了对你的情怀, 飘飘然, 飘飘然, 送到你的面前。 轻轻浮动你的...
    等待昇華阅读 212评论 0 0
  • 文:通灵半藏 最近,我很有时间和精力在公众号上搞图文,于是都很简略地发了一点文字和图片。大家可能看不出有什么意义。...
    通灵半藏阅读 479评论 0 0
  • 何甲荣画怎样
    邓灯光阅读 181评论 0 0