当前位置: 首页 > news >正文

【困难】题解力扣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 = []
输出:[]

示例 3:
输入:lists = [[]]
输出:[]

提示:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按升序排列
  • lists[i].length 的总和不超过 10^4

解题思路

采用分治法 + 迭代合并策略高效合并 K 个有序链表:

  1. 边界处理
  • 若链表数组为空或长度为 0,直接返回 null
  • 若只有一个链表,无需合并,直接返回该链表
  1. 分治合并
  • 初始化当前链表数量 n = lists.length
  • n > 1 时循环:
    • 计算新链表数量 newN = (n + 1) / 2
    • 遍历链表数组,每次处理两个链表:
      • 合并 lists[2*i]lists[2*i+1](若存在)
      • 将合并结果存回 lists[i] 位置
    • 更新 n = newN 进行下一轮合并
  • 最终合并结果位于 lists[0]
  1. 合并两个链表
  • 使用哑节点 dummy 简化链表头处理
  • 双指针遍历两个链表,比较节点值,将较小节点接入新链表
  • 当一个链表遍历完时,将另一链表剩余部分直接接入

代码实现(Java版)

class Solution {public ListNode mergeKLists(ListNode[] lists) {int n = lists.length;if (n == 0) return null;if (n == 1) return lists[0];while (n > 1) {int newN = (n + 1) / 2;for (int i = 0; i < n / 2; i++) {lists[i] = mergeTwoLists(lists[2 * i], lists[2 * i + 1]);}if (n % 2 == 1) {lists[newN - 1] = lists[n - 1];}n = newN;}return lists[0];}private ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode dummy = new ListNode();ListNode cur = dummy;while (l1 != null && l2 != null) {if (l1.val <= l2.val) {cur.next = l1;l1 = l1.next;} else {cur.next = l2;l2 = l2.next;}cur = cur.next;}cur.next = (l1 != null) ? l1 : l2;return dummy.next;}
}

代码说明

  1. 主方法 mergeKLists
  • 边界处理:直接处理空数组或单链表情况
  • 分治合并
    • n 表示当前待合并的链表数量
    • newN = (n + 1) / 2 计算合并后链表数量
    • 循环合并相邻链表:lists[i] = mergeTwoLists(lists[2*i], lists[2*i+1])
    • 处理奇数链表:将最后一个链表移至 newN-1 位置
    • 更新 n = newN 进行下一轮合并
  • 返回 lists[0]:最终合并结果
  1. 辅助方法 mergeTwoLists
  • 哑节点dummy 统一处理头节点
  • 双指针遍历
    • 比较 l1l2 节点值,较小者接入新链表
    • 移动对应链表指针及新链表指针 cur
  • 剩余链表处理:循环结束后将非空链表剩余部分直接接入

提交详情(执行用时、内存消耗)

在这里插入图片描述

http://www.dtcms.com/a/283779.html

相关文章:

  • 删除百度同步空间桌面图标
  • 面试高频题 力扣 200.岛屿数量 洪水灌溉 深度优先遍历 暴力搜索 C++解题思路 每日一题
  • 用Amazon Q Developer命令行工具(CLI)快捷开发酒店入住应用程序
  • 图片画廊浏览(侧重 CSS 网格布局和模态框交互)
  • onUnload页面卸载和onPageScroll监听页面滚动
  • EPLAN 电气制图(十): 绘制继电器控制回路从符号到属性设置(上)
  • C++编程学习(第九天)
  • FastAdmin系统框架通用操作平滑迁移到新服务器的详细步骤-优雅草卓伊凡
  • btstack移植之安全配对(二)
  • 【Linux-云原生-笔记】LVS(Linux virual server)相关
  • C strtok函数应用
  • c++ 模板元编程
  • 深入解析Hadoop HDFS高可用性:原理、故障切换与元数据同步
  • 【AI论文】T-LoRA:无过拟合的单图像扩散模型定制化方案
  • MailAgentProcess.getInstance
  • 进程终止机制详解:退出场景、退出码与退出方式全解析
  • Django中get()与filter()对比
  • 3D材质总监的“光影魔法”:用Substance Sampler AI,“擦除”照片中的光影
  • 3D Gaussian Splatting (3DGS) 从入门到精通:安装、训练与常见问题全解析
  • 如何构建一个基于大模型的实时对话3D数字人?
  • 【代码随想录】+ leetcode hot100:栈与队列算法专题总结、单调栈
  • 【leetcode】852. 山脉数组的封顶索引
  • MySQL数据库主从复制
  • 如何将 ONLYOFFICE 文档集成到使用 Laravel 框架编写的 PHP 网络应用程序中
  • 7.事务操作
  • 第2章通用的高并发架构设计——2.6 高并发写场景方案1:数据分片之数据库分库分表
  • win10 安装mysql启动
  • 配置mysql
  • ONLYOFFICE Docs 9.0 重磅上线:全面升级界面体验,AI 驱动高效办公
  • Java全栈工程师面试实录:从电商支付到AI大模型架构的深度技术挑战