LeetCode-23-合并K个升序链表

LeetCode力扣真题解惑第3篇 —— 力扣第23题:合并K个升序链表 LeetCode力扣真题解惑第2篇 —— 力扣第23题:合并K个升序链表 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4-&gt 阅读详情

题目

来源:LeetCode.

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

提示:

  • k = = l i s t s . l e n g t h k == lists.length k==lists.length
  • 0 < = k < = 1 0 4 0 <= k <= 10^4 0<=k<=104
  • 0 < = l i s t s [ i ] . l e n g t h < = 500 0 <= lists[i].length <= 500 0<=lists[i].length<=500
  • − 1 0 4 < = l i s t s [ i ] [ j ] < = 1 0 4 -10^4 <= lists[i][j] <= 10^4 −104<=lists[i][j]<=104
  • l i s t s [ i ] lists[i] lists[i] 按 升序 排列
  • l i s t s [ i ] . l e n g t h lists[i].length lists[i].length 的总和不超过 1 0 4 10^4 104

接下来看一下解题思路:

思路一:顺序合并:

    可以遍历链表;
    将链表里的两个值采用 LeetCode-21-合并两个有序链表. 有序合并;
    然后将合并的结果与数据里的值依次合并,返回最终结果;

public static ListNode mergeKLists1(ListNode[] lists) {
    if (lists == null || lists.length < 1) {
        return null;
    }
    if (lists.length < 2) {
        return lists[0];
    }
    ListNode cur = lists[0];
    for (int i = 1; i < lists.length; ++i) {
        cur = mergeList(cur, lists[i]);
    }
    return cur;
}

private static ListNode mergeList(ListNode p1, ListNode p2) {
    if (p1 == null) {
        return p2;
    }
    if (p2 == null) {
        return p1;
    }
    ListNode dummy = new ListNode(0, p1);
    ListNode pred = dummy;
    while (p1 != null && p2 != null) {
        if (p1.val > p2.val) {
            pred.next = p2;
            p2 = p2.next;
        } else {
            pred.next = p1;
            p1 = p1.next;
        }
        pred = pred.next;
    }
    pred.next = (p1 == null) ? p2 : p1;
    return dummy.next;
}
总结

    时间复杂度:假设每个链表的最长长度是 n n n。在第一次合并后, c u r cur cur 的长度为 n n n;第二次合并后, c u r cur cur 的长度为 2 × n 2\times n 2×n,第 i i i 次合并后, c u r cur cur 的长度为 i × n i\times n i×n。第 i i i 次合并的时间代价是 O ( n + ( i − 1 ) × n ) = O ( i × n ) O(n + (i - 1) \times n) = O(i \times n) O(n+(i−1)×n)=O(i×n),那么总的时间代价为 O ( ∑ i = 1 k ( i × n ) ) = O ( ( 1 + k ) ⋅ k 2 × n ) = O ( k 2 n ) O(\sum_{i = 1}^{k} (i \times n)) = O(\frac{(1 + k)\cdot k}{2} \times n) = O(k^2 n) O(∑i=1k​(i×n))=O(2(1+k)⋅k​×n)=O(k2n),故渐进时间复杂度为 O ( k 2 n ) O(k^2 n) O(k2n)。

    空间复杂度:空间复杂度为 O ( 1 ) O(1) O(1)。

思路二:分治合并:

    考虑优化方法一,用分治的方法进行合并。
    将 k k k 个链表配对并将同一对中的链表合并;
    重复这一过程,直到我们得到了最终的有序链表。

public static ListNode mergeKLists3(ListNode[] lists){
   if (lists == null || lists.length < 1) {
       return null;
   }
   if (lists.length < 2) {
       return lists[0];
   }

   return merge(lists, 0, lists.length - 1);
}

private static ListNode merge(ListNode[] lists, int start, int end) {
   if (start == end) {
       return lists[start];
   }
   if (start > end) {
       return null;
   }
   int mid = (start + end) >> 1;
   return mergeList(merge(lists, start, mid), merge(lists, mid + 1, end));
}
private static ListNode mergeList(ListNode p1, ListNode p2) {
   if (p1 == null) {
       return p2;
   }
   if (p2 == null) {
       return p1;
   }
   ListNode dummy = new ListNode(0, p1);
   ListNode pred = dummy;
   while (p1 != null && p2 != null) {
       if (p1.val > p2.val) {
           pred.next = p2;
           p2 = p2.next;
       } else {
           pred.next = p1;
           p1 = p1.next;
       }
       pred = pred.next;
   }
   pred.next = (p1 == null) ? p2 : p1;
   return dummy.next;
}
总结

    时间复杂度:考虑递归「向上回升」的过程——第一轮合并 k 2 \frac{k}{2} 2k​
组链表,每一组的时间代价是 O ( 2 n ) O(2n) O(2n);第二轮合并 k 4 \frac{k}{4} 4k​ 组链表,每一组的时间代价是 O ( 4 n ) O(4n) O(4n)…所以总的时间代价是 O ( ∑ i = 1 ∞ k 2 i × 2 i n ) = O ( k n × log ⁡ k ) O(\sum_{i = 1}^{\infty} \frac{k}{2^i} \times 2^i n) = O(kn \times \log k) O(∑i=1∞​2ik​×2in)=O(kn×logk),故渐进时间复杂度为 O ( k n × log ⁡ k ) O(kn \times \log k) O(kn×logk)。

    空间复杂度:递归会使用到 O ( log ⁡ k ) O(\log k) O(logk) 空间代价的栈空间。

思路三:使用优先队列合并:

    可以维护一个队列;
    每次在这些元素里面选取 val 属性最小的元素合并到答案中
    在选取最小元素的时候,我们可以用优先队列来优化这个过程。

public static ListNode mergeKLists(ListNode[] lists) {
    if (lists == null || lists.length < 1) {
        return null;
    }
    if (lists.length < 2) {
        return lists[0];
    }

    PriorityQueue<ListNode> queue = new PriorityQueue<>((node1, node2) -> {
        return node1.val - node2.val;
    });

    ListNode dummmy = new ListNode(0);
    ListNode node = dummmy;
    for (ListNode list : lists) {
        if (list != null) {
            queue.add(list);
        }
    }
    while (!queue.isEmpty()) {
        ListNode temp = queue.poll();
        if (temp.next != null) {
            queue.add(temp.next);
        }
        node.next = temp;
        node = node.next;
        node.next = null;
    }
    return dummmy.next;
}
总结

    时间复杂度:考虑优先队列中的元素不超过 k k k 个,那么插入和删除的时间代价为 O ( log ⁡ k ) O(\log k) O(logk),这里最多有 k n kn kn 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 O ( k n × log ⁡ k ) O(kn \times \log k) O(kn×logk)。
    空间复杂度:这里用了优先队列,优先队列中的元素不超过 k k k个,故渐进空间复杂度为 O ( k ) O(k) O(k)。

Leetcode-每日一题【23.合并 K 个升序链表】 给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。链表数组如下:1->4->5,1->3->4,2->6将它们合并到一个有序链表中得到。 阅读详情

相关推荐

【困难】力扣算法题解析LeetCode23:合并K个升序链表

本文介绍了如何高效合并K个有序链表的方法。通过分治法将问题分解为两两合并子任务,大幅降低时间复杂度。具体实现时,先处理边界情况,然后迭代合并链表对,最终得到完全合并的链表。算法时间复杂度为O(NlogK),其中N为总节点数,K为链表数量。Java代码展示了分治合并的核心逻辑,包括哑节点处理、双指针比较和剩余链表连接等关键步骤。

ylumwd的博客 607

给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表

基本思路:想要合并多个升序的链表,前提是需要会合并两个升序排列的链表。具体的方法在之前的博文中有提及合并两个有序的链表 大概的思路和合并两个有序数组基本相同,就是在链表的最开始确定两个指针,根据指针来确定哪个链表的元素更小一点,将小的哪个链表移入到合并的链表中并后移以为,然后继续比较最前面的指针,重复以上的步骤直到一个链表为空,说明另外一个链表中存在的数都是最大的数,只需要将他们连接到合并链表的后面就完成了。 合并多个链表就是循环合并两个链表的过程,我们合并第一个第二个链表生成一个新的链表,然后用这个新生成

guiguchunqiu的博客 2801

LeetCode 23 - 合并K个升序链表

是一类经典的合并问题,侧重考察数据结构(如优先队列/堆、分治归并)以及对链表操作的熟练程度。它的变体也常见于工程代码面试和ACM竞赛中,被列为必备技能是一点也不冤。下面就详细分析各种解法及模板代码,以及经典变体问题和快速AC技巧。给定一个数组lists,数组中每个元素为一个升序链表,要求将所有链表合并为一个升序链表,并返回合并后的链表。

互联网架构师笔记 992

LeetCode 23.合并k个升序链表

看到这个题首相想到的就是暴力转化破解,思路就是把链表的所有结点值放进一个数组里面,对这个数组排序,我们可以用vector动态创建,完事之后,对数组进行从小到大的默认排序,最后遍历整个数组根据值去创建一个一个新的结点,把这些结点串在一起返回就行。都知道优先级队列底层是拿堆实现的,默认的大顶堆,每次把元素放进优先队列里,他会自动给你排序,对头就是优先级最高的那个,这里的优先级可能是大小可能是什么的,对于自定义的类型我们可以自定义他的排序方式。输入:lists = [[1,4,5],[1,3,4],[2,6]]

oorik的博客 1983

别再只测电压了!用STM32G474的ADC玩点花的:过采样提升精度与多通道扫描实战

本文深入探讨了STM32G474系列单片机的ADC高级应用,包括硬件过采样技术实现16位精度和多通道扫描结合DMA的自动数据采集方案。通过详细的配置步骤和实战案例,帮助开发者突破传统电压测量局限,提升信号采集精度和系统效率,适用于工业监控、医疗设备等高精度应用场景。

weixin_42647395的博客 237

保姆级教程:在RK3568上搞定PR2100K+GC2385双摄(从DTS配置到HAL层补丁)

本文详细介绍了在RK3568平台上调试PR2100K+GC2385双摄系统的完整流程,从DTS配置到HAL层补丁。涵盖硬件连接、媒体控制器拓扑验证、Camera3配置、HAL层特殊补丁及性能优化等关键步骤,帮助开发者快速解决双摄调试中的常见问题,提升嵌入式视觉系统开发效率。

weixin_28724661的博客 195

【LeetCode刷题(困难程度)】23. 合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6 示例 2: 输入:lists =...

qq_33197518的博客 415

ComfyUI实战:AnimateDiff与ControlNet结合,打造无缝风格化视频转绘

本文详细介绍了如何利用ComfyUI平台,结合AnimateDiff与ControlNet插件,实现高质量的视频风格化转绘。通过搭建节点工作流、调整关键参数,有效解决画面闪烁与失真问题,并分享了进阶玩法与常见问题解决方案,帮助用户轻松打造流畅、风格统一的动态视觉效果。

weixin_29039773的博客 334

链表-23.合并K个升序链表-力扣(LeetCode)

black_bear_white的博客 951

宇树机器人G1二次开发:导览、起始点、目的地与完整示例

通过宇树G1 SDK的导航接口,开发者可以高效地实现机器人的自主移动功能。连接 -> 设置目标点 -> 发送命令 -> 监控状态。本文提供的完整示例涵盖了从环境搭建到代码实现的全部步骤,并解释了起始点、目的地等关键概念。开发者可以在此基础上,结合多目标点巡逻、动态避障(需高级配置)等功能,构建更复杂的机器人应用。建议读者先在小范围、熟悉的平坦环境中测试,成功后再逐步扩展到更复杂的场景。

m0_52645558的博客 746

CST实战:变容二极管电容曲线提取全流程(附S参数设置技巧)

本文详细介绍了在CST Studio Suite中提取变容二极管电容-电压(C-V)曲线的完整实战流程。重点解析了S参数仿真的核心原理、DCFEED模块的正确配置、参数扫描的设置技巧,并探讨了集成SPICE模型进行精确仿真的方法,帮助射频工程师高效、准确地获取器件关键特性。

weixin_29237635的博客 529

【算法入门】LeetCode 23. 合并K个升序链表(Merge k Sorted Lists)详细指南|力扣 23 题:合并 K 个升序链表——优先队列(最小堆)详解(Java & js双解法

给你一个链表数组lists,每个链表都已经按升序排列。请你将它们合并成一个升序链表并返回。输入:lists = [[1,4,5],[1,3,4],[2,6]]输出:1->1->2->3->4->4->5->6链表个数k范围:0 ≤ k ≤ 10^4所有链表元素总和不超过 10^4链表节点值范围:-10^4 到 10^4**两两合并:**将链表两两合并,逐步缩减到一个链表,时间复杂度较高。**分治思想:**用递归每次合并一半链表,提高效率。利用优先队列管理多个链表,保持高效。

南北极之间 1373

Type-C连接中的CC引脚:Rp与Rd电阻的识别与供电模式选择

本文深入解析Type-C接口中CC引脚的核心功能,包括Rp与Rd电阻的识别原理及供电模式选择机制。通过详细的分压计算和实战案例,揭示Type-C设备如何通过CC引脚实现方向检测、角色识别和供电协商,为硬件设计提供关键指导。

weixin_30616969的博客 341

23. 合并 K 个升序链表 - 力扣(LeetCode)

对于合并多个已排序的列表或链表,一种常见的算法是使用最小堆(Min Heap)。在这个问题中,我们可以利用Python的。Java:方法、while循环、for循环、PriorityQueue类、if判断。Python: 方法、while循环、for循环、heapq 模块、if判断。请你将所有链表合并到一个升序链表中,返回合并后的链表。给你一个链表数组,每个链表都已经按升序排列。模块不了解的,可以看一下我的这篇文章。将它们合并到一个有序链表中得到。

it爱好者的学习之路 1208

告别城市峡谷定位漂移:手把手教你用PSINS仿真INS/NHC/ODO组合导航(附代码获取)

本文详细解析了INS/NHC/ODO组合导航系统在城市峡谷环境中的应用,通过PSINS平台实现精准定位。文章涵盖核心原理、环境搭建、算法实现及性能优化,帮助开发者解决GNSS信号中断时的定位漂移问题,提升自动驾驶系统在复杂环境中的可靠性。

weixin_30329623的博客 429

浏览器解析HTML的过程及编程实现

需要注意的是,上述示例代码只是简化的演示,并未涵盖浏览器解析HTML的所有细节和复杂性。实际上,浏览器的HTML解析引擎还会处理一系列的特殊情况、错误容错和性能优化等方面的内容,以确保能够正确解析各种类型的HTML代码。HTML(超文本标记语言)是构建网页的基础语言,浏览器负责将HTML代码解析并渲染成可视化的网页。本文将详细介绍浏览器解析HTML的过程,并提供相应的编程示例代码。希望以上内容能帮助您理解浏览器解析HTML的过程,并通过提供的示例代码更好地了解如何在编程中实现这一过程。

ByteJolt的博客 321

23.合并k个升序序链表- 力扣(LeetCode)

八八合并:把 lists[0] 和 lists[4] 合并(相当于合并前八条链表),合并后的链表保存在 lists[0] 中;四四合并:把 lists[0] 和 lists[2] 合并(相当于合并前四条链表),合并后的链表保存在 lists[0] 中;把 lists[4] 和 lists[6] 合并,合并后的链表保存在 lists[4] 中;例如有三个链表 1->2->5, 3->4->6, 4->5->6,找到第一个节点 1 之后,第二个节点不是另一个链表的头节点,而是节点 1 的下一个节点 2。

2401_87004385的博客 1559

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

LeetCode 23:合并 K 个升序链表

本文介绍了合并K个升序链表的两种高效解法。优先队列法通过维护最小堆动态获取最小节点,时间复杂度O(NlogK),空间O(K)。分治合并法采用递归分治策略,先两两合并再递归合并结果,同样时间复杂度O(NlogK)但空间更优O(logK)。两种方法都能高效解决问题,优先队列实现直观,分治合并空间更优。示例验证了两种方法的正确性,根据实际需求选择适合的解法即可。

m0_75126572的博客 1201

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

LeetCode--23.合并k个升序链表

解题思路: 1.获取信息: 给出了多个升序链表,要求合并成一个升序链表,返回首元结点 2.分析题目: 外面在21题的时候,讲了怎样合并两个升序链表为一个升序链表,不了解的,建议去看一下21题题解,不要好高骛远 (有时候一个问题比较难,将它拆分成多个小问题取逐一解决是一个不错的方法) 好了,那我们现在知道怎么合并两个有序链表了,类比推理,我们可以将这个问题看作是两

dying_man的博客 1897

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

LeetCode 23:合并 K 个升序链表,Java 小顶堆解法详解

本文介绍了使用小顶堆(优先队列)合并K个升序链表的解法。通过维护一个大小为K的小顶堆,每次取出堆顶最小节点并加入其后继节点,确保堆中始终保存各链表的当前候选节点。这种算法的时间复杂度为O(NlogK),空间复杂度为O(K),相比直接遍历K条链表的O(NK)方案更高效。文章详细讲解了思路推导、Java实现、复杂度分析和常见错误,并指出优先使用Integer.compare()避免整数溢出。此外还提到了分治合并的替代方案,两者时间复杂度相同但实现思路不同。

weixin_51228134的博客 1万+

[分治] leetcode 23 合并K个升序链表

[分治] leetcode 23 合并K个升序链表 1.题目 题目链接 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例: 输入:n = 3 输出:[ "((()))", "(()())", "(())()", "()(())", "()()()" ] 2.分析 2.1.直观解法 为了求某种有效的组合,我们可以把所有可能的组合都列出来,然后逐个判断各个组合是否有效。这就

xiongxyowo的博客 292

golang力扣leetcode 23.合并K个升序链表

23.合并K个升序链表23.合并K个升序链表题解代码 23.合并K个升序链表 23.合并K个升序链表 题解 没啥含金量,就更归并排序一样,考验基本功吧 代码 type ListNode struct { Val int Next *ListNode } func mergeKLists(lists []*ListNode) *ListNode { dummy := &ListNode{} for _, v := range lists { dummy.Next = merge(dum

清风 1046

LeetCode高频题23. 合并K个升序链表

1)这种题目,思想重要,topK资源限制情况下,统计词频最高的那些,或者这种按照不同数组升序情况下,整体排序的事情,都要小根堆,让每个链表都有一个元素在堆中,整体谁小,谁先冒出来。 2)小根堆排序复杂度log(n)速度快,之前咱们求不同数组中,必须包含每个数组至少1个数的最窄区间a--b,那种就是利用小根堆,把每个数组,至少放一个元素在小根堆中,这样弹出来的最小最大值,就是区间,而且还包含至少每个数组一个元素。 3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。.

weixin_46838716的博客 1187

【链表系列 - 8】【力扣每日一题 0812】LEETCODE 23. 合并K个升序链表

法三:利用优先队列,把每个有序列表的未合并的头节点加入到优先队列,每次优先队列弹出最小的元素即可。力扣 每日一题 合并K个升序链表 23 模拟 归并 优先队列。法二:考虑分治的思想,采用归并的方式进行合并,所以共需合并。remove_if搭配erase清除空的指针元素。法一:最朴素的想法,直接两两合并,时间复杂度。给k个升序链表,要求将他们合并。优先队列的自动推导类型和初始化。③ new和delete。

weixin_54010404的博客 229

【力扣】23. 合并 K 个升序链表 <链表指针、堆排序、分治>

【力扣】23. 合并 K 个升序链表

学习笔记 992

LeetCode第23题_合并K个升序链表

这是一道综合性的算法题目:考察分治思想的应用考察优先队列的使用考察链表操作的基本功两种解法比较:分治:实现简单,空间效率好优先队列:时间效率稳定,但需要额外空间优化思路:可以使用迭代而不是递归来实现分治优先队列可以使用数组实现考虑链表长度的平衡性。

qq_40263592的博客 1013
上一篇: LeetCode-22-括号生成
下一篇: LeetCode-24-两两交换链表中的节点
CodAlun
博客等级 码龄8年 46粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值