zoukankan      html  css  js  c++  java
  • 23.合并K个排序链表(Merge k Sorted Lists)

    题目描述:

    合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

    示例:

    输入:
    [
      1->4->5,
      1->3->4,
      2->6
    ]
    输出: 1->1->2->3->4->4->5->6

    解题思路:

      合并k个排序链表,方法有很多。比如最开始相当的就是先合并前两个链表,然后依次合并接下来的链表,不过这样写时间复杂度很高,因为有很多重复遍历的操作。接着会想到先全部取到一个容器中,然后再进行后续的操作。接下来我们讨论全部取到一个容器中的思路。

      很容易想到的是,我们直接依次遍历k个链表的所有结点,然后全部直接放在vector或是别的什么容器中,再对容器中的元素进行排序,最后导出元素为一个链表。这样假设有n个元素,则插入的时间复杂度是O(n),排序是O(nlgn),导出是O(n),总时间复杂的数量级在nlgn,不过系数会很大。

      上面的那种想法显然浪费了k个链表是已排序的特点,那如何利用这个条件呢?我想到的是,每次比较k的链表的第一个元素,取出其中最小的那个元素,作为返回链表的表头,然后被取出元素的指针向下移动。再次和另外两个结点比较,取出最小的那个,加在返回链表的尾部,依次往复。这样最坏情况下每插入一个元素都要比较k次,假设有一共有n个元素,则时间复杂度为O(k*n)。

      可见用哪种方法取决于k和n的大小,但是题目所给出的链表并不能直接返回长度,所以为了方便起见,我直接把所有元素都插入到multiset中,然后再依次导出。

      代码如下:

    /**
     * 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 nullptr;
            multiset<int> ret;
            for (auto l : lists) {
                auto p = ret.begin();
                while (l != nullptr) {
                    p = ret.insert(p, l->val);
                    l = l->next;
                }
            }
            if (ret.empty())
                return nullptr;
            auto p = ret.begin();
            ListNode *start = new ListNode(*p);
            ListNode *end = start;
            for (++p; p != ret.end(); ++p) {
                end->next = new ListNode(*p);
                end = end->next;
            }
            return start;
        }
    };
  • 相关阅读:
    一种安全云存储方案设计(上)——基于二次加密的存储策略与加密图文混合检索
    lamda表达式导致运行时VerifyError
    编译原理:语法分析概述
    语音识别与 RNN-Transducer 概述
    通信原理基本概念
    追光捉影的自动机:2021 卓工实训小作文
    【实战】jsfinder+jsinfo-scan结合改造
    js基础记录
    qq、微信二次分享
    收藏链接
  • 原文地址:https://www.cnblogs.com/yxsrt/p/12703362.html
Copyright © 2011-2022 走看看