【LeetCode 热题 100】21. 合并两个有序链表——(解法一)迭代法

Problem: 21. 合并两个有序链表
题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(M + N)
    • 空间复杂度:O(1)

整体思路

这段代码旨在解决一个基础且经典的链表问题:合并两个有序链表 (Merge Two Sorted Lists)。问题要求将两个已按升序排列的链表合并为一个新的、仍然保持升序的链表。

该算法采用了一种非常标准和高效的 “迭代法”,通过一个 “虚拟头节点(Dummy Node)” 技巧来简化代码逻辑。

  1. 虚拟头节点(Dummy Node)的作用

    • 算法首先创建了一个名为 dummy 的新节点。这个节点本身不存储任何有效数据,它的主要作用是作为新合并链表的哨兵占位符
    • 优势:使用 dummy 节点可以避免处理“新链表为空”的边界情况。我们始终可以安全地向 dummy.next 添加第一个有效节点,而无需编写 if (newList == null) 这样的判断。最后,我们只需返回 dummy.next 即可得到真正的新链表头。
    • 一个 tail 指针被初始化为 dummy,它将始终指向新合并链表的尾部,用于方便地追加新节点。
  2. 迭代合并

    • 算法使用一个 while 循环,只要两个输入链表 list1list2不为空,就持续进行比较和合并。
    • 在循环的每一步,比较 list1.vallist2.val 的大小:
      • 如果 list1.val < list2.val:说明 list1 的当前节点值更小,应该被先加入到新链表中。于是,将 tail.next 指向 list1,然后将 list1 指针向前移动一步 (list1 = list1.next)。
      • 否则 (list1.val >= list2.val):说明 list2 的当前节点值更小或相等,它应该被加入新链表。将 tail.next 指向 list2,然后移动 list2 指针。
    • 在将一个节点链接到新链表后,必须将 tail 指针也向前移动 (tail = tail.next),使其始终指向新链表的最后一个节点,为下一次追加做准备。
  3. 处理剩余部分

    • while 循环结束时,意味着 list1list2(或两者都)已经为空。
    • 此时,最多只有一个链表还有剩余的节点。由于输入链表本身就是有序的,这个剩余的部分也必然是有序的,并且其所有节点的值都大于或等于已合并链表中的所有值。
    • 因此,我们无需再逐个比较,直接将 tail.next 指向那个非空的剩余链表即可。
    • 代码 tail.next = list1 != null ? list1 : list2; 巧妙地实现了这一逻辑。
  4. 返回结果

    • 最后,返回 dummy.next,它指向新合并链表的真正头节点。

完整代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {/*** 将两个升序链表合并为一个新的升序链表。* @param list1 第一个有序链表的头节点* @param list2 第二个有序链表的头节点* @return 合并后新链表的头节点*/public ListNode mergeTwoLists(ListNode list1, ListNode list2) {// 创建一个虚拟头节点(dummy node),作为新链表的哨兵。ListNode dummy = new ListNode();// tail 指针用于追踪新链表的尾部,方便追加节点。ListNode tail = dummy;// 步骤 1: 迭代比较和合并,直到其中一个链表为空。while (list1 != null && list2 != null) {// 比较两个链表当前节点的值if (list1.val < list2.val) {// 如果 list1 的值更小,将 list1 的当前节点链接到新链表尾部tail.next = list1;// 移动 list1 的指针到下一个节点list1 = list1.next;} else {// 否则,将 list2 的当前节点链接到新链表尾部tail.next = list2;// 移动 list2 的指针到下一个节点list2 = list2.next;}// 无论哪个节点被链接,都要将 tail 指针移动到新链表的当前末尾tail = tail.next;}// 步骤 2: 处理剩余的链表部分。// 循环结束后,最多只有一个链表还有剩余节点。// 直接将新链表的尾部链接到这个剩余链表的头部。tail.next = (list1 != null) ? list1 : list2;// 步骤 3: 返回虚拟头节点的下一个节点,即新链表的真正头节点。return dummy.next;}
}

时空复杂度

时间复杂度:O(M + N)

  1. 循环分析
    • 算法的核心是 while 循环。在每次迭代中,list1list2 中的一个指针会向前移动一步。
    • 这个循环会一直持续到其中一个链表被完全遍历完。
    • list1 的长度为 Mlist2 的长度为 Nwhile 循环的总迭代次数等于 MN 中较小者的长度。
    • 处理剩余部分的操作是 O(1)。
    • 总的来说,算法需要遍历两个链表的所有节点恰好一次。

综合分析
算法的时间复杂度与两个链表的总长度成线性关系,即 O(M + N)

空间复杂度:O(1)

  1. 主要存储开销:该算法是在原地重新链接(re-wire)输入链表的节点,并没有为新链表创建新的节点。
  2. 辅助变量:只创建了 dummytail 两个额外的指针变量。这些变量的数量是固定的,与链表长度无关。

综合分析
算法所需的额外辅助空间是常数级别的。因此,其空间复杂度为 O(1)。这是一个空间效率最优的迭代解法。

【LeetCode 热题 100】21. 合并两个有序链表——(解法二)递归法

参考灵神

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90520.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 hot100 Day40

23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 //自己写的垃圾 class Solution { public:ListNode* mergeKLists(vector<ListNode*>& lists) {vector<int…

validate CRI v1 image API for endpoint “unix:///run/containerd/containerd.sock“

1.现象pull image failed: Failed to exec command: sudo -E /bin/bash -c "env PATH$PATH crictl pull 172.23.123.117:8443/kubesphereio/pause:3.9"FATA[0000] validate service connection: validate CRI v1 image API for endpoint "unix:///run/container…

【会员专享数据】2013-2024年我国省市县三级逐月SO₂数值数据(Shp/Excel格式)

之前我们分享过2013-2024年全国范围逐月SO₂栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;!该数据来源于韦晶博士、李占清教授团队发布在国家青藏高原科学数据中心网站上的中国高分辨率高质量近地表空气污染物数据集。很多小伙伴拿到数据后反馈栅格数据不太方便使…

锐捷网络重磅发布RG-UNC CS网络数字化平台:四大核心能力重塑企业网络管理新范式

近期&#xff0c;锐捷重磅发布RG-UNC网络数字化平台CS系列产品&#xff0c;通过全网统一融合管理、组网编排及自动化部署、便捷准入与访问控制、全链业务保障与可视四大核心能力&#xff0c;重新定义企业网络管理标准。置身于数字化转型的进程中&#xff0c;您的网络是否还在面…

使用虚拟机远程登陆ensp模拟器交换机

本文使用软件&#xff1a;VMware&#xff0c;eNSP&#xff0c;mobaxterm要登陆ensp里面的设备&#xff0c;需要使用到cloud下面我们先搭建如下拓扑&#xff1a;首先点击cloud&#xff0c;端口一绑定UDP信息&#xff0c;添加&#xff1b;端口2绑定VMnet8网卡&#xff08;注意网段…

显卡GPU的架构和工作原理

显卡GPU&#xff08;图形处理单元&#xff09;是专为并行计算和图形处理设计的芯片&#xff0c;广泛应用于游戏、科学计算、人工智能和数据中心等领域。以下详细介绍GPU的架构和工作原理&#xff0c;涵盖核心组件、计算流程和关键技术&#xff0c;尽量简洁清晰。 一、GPU架构概…

AndFix、Robust 与 Tinker 热修复框架深度对比

AndFix、Robust 与 Tinker 热修复框架深度对比 在 Android 热修复领域&#xff0c;AndFix、Robust 和 Tinker 是三种主流的解决方案&#xff0c;它们在实现原理、使用场景和限制条件上有显著差异。以下是三者的详细对比分析&#xff1a; 一、核心原理对比特性AndFixRobustTinke…

FlashAttention 快速安装指南(避免长时间编译)

简介&#xff1a;FlashAttention 编译太慢&#xff1f;本篇提供无需编译的预编译 wheel 快速安装方案&#xff0c;适配多版本 Python、PyTorch 和 CUDA&#xff0c;极大节省部署时间&#xff01; &#x1f4a1; 背景介绍 FlashAttention 是由 DAO Labs 提出的一种高性能 atten…

openresty增加tcp端口转发

openresty增加tcp端口转发 1.配置文件nginx.conf 增加stream模块 stream {include /etc/nginx/conf.d/stream/*.conf; }2.在nginx/conf/目录下创建个stream文件夹 新增个10000.conf配置文件server {listen 10000;proxy_pass data_tcp; upstream data_tcp {server 10.10.10.2:10…

动态物体滤除算法

图像层面&#xff1a;2D图像分割反投影到3D点云滤除 基于分割 原理&#xff1a;通过2D语义分割&#xff08;如DeepLab、Mask R-CNN&#xff09;识别动态物体&#xff08;车辆、行人&#xff09;&#xff0c;将分割结果反投影至3D点云中滤除。优化方向&#xff1a; 结合时序一致…

Redisson是如何实现分布式锁的?

Redisson 如何实现分布式锁&#xff1f;&#xff08;核心原理与思考&#xff09; Redisson 是一个功能强大的 Redis 客户端&#xff0c;它提供了许多分布式对象和服务&#xff0c;其中就包括分布式锁。Redisson 的分布式锁是基于 Redis 的 Lua 脚本实现的&#xff0c;这保证了操…

Java 导出word 实现饼状图导出--可编辑数据

&#x1f4ca; 支持图表导出功能&#xff01; 支持将 柱状图、折线图 图表以 Word 文档格式导出&#xff0c;并保留图例、坐标轴、颜色、数据标签等完整信息。 如需使用该功能&#xff0c;请私聊我&#xff0c;备注 “导出柱状图 / 折线图”。 生成的效果图如下&#xff1a;示例…

AI大模型平台

在科技浪潮迅猛推进的当下&#xff0c;AI大模型平台宛如一颗璀璨的新星&#xff0c;强势闯入大众视野&#xff0c;以其独特的魅力和强大的功能&#xff0c;深刻地变革着我们生活与工作的每一处角落。从日常智能助手的贴心陪伴&#xff0c;到专业内容创作的灵感激发&#xff1b;…

C# Console App生成的 dll文件

在使用 dotnet 8.0 创建一个 C# console app后&#xff0c;执行完编译操作&#xff0c;会发现除了生成可执行文件外&#xff0c;还生成一个 dll文件。 $ls ConsoleApp1 ConsoleApp1.dll ConsoleApp1.runtimeconfig.json ConsoleApp1.deps.json ConsoleApp1.pdb $ …

【AI】环境——深度学习cuda+pytorch配置

文章目录关键组件及关系显卡驱动GPU DriverCUDACUDA ToolkitcuDNNPytorch各组件版本选择驱动程序CUDA查看驱动及CUDA的最大支持版本CUDA Toolkit选自定义安装检验无法识别nvcccuDNNcondapip换源conda管理py包conda 换源查看列表、创建、克隆、激活、删除conda包管理包安装原则设…

观众信息设置与统计(视频高级分析与统计功能)

Web播放器&#xff08;POLYV-html5-player&#xff09;支持设置观众信息参数&#xff0c;设置后在播放器上报的观看日志中会附带观众信息&#xff0c;这样用户就可以通过管理后台的统计页面或服务端API来查看特定观众的视频观看情况了。 一、观众信息设置 播放器设置观众信息参…

《数据库》 MySQL库表操作

1. SQL语句基础 1.2 SQL简介 SQL&#xff1a;结构化查询语言(Structured Query Language)&#xff0c;在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句&#xff0c;程序员和数据库管理员可以完成如下的任务 改变数据库的结构 更改系统的安全设置…

DSP的基础平台搭建

1、CCS6.0的安装安装步骤这里就不说了&#xff0c;只谈论最可能遇到的问题&#xff1a;可以看到为需要关闭防火墙和扫描&#xff1b;在这里将其都关闭&#xff0c;然后可以断掉网络&#xff0c;关闭联想管家&#xff0c;可能还是会出现防火墙提示&#xff0c;但是可以安装&…

下一代防火墙-终端安全防护

实验设备1、 山石网科&#xff08;hillstone&#xff09;系列下一代防火墙&#xff08;实训平台v1.0中hillstone设备&#xff09;2、 三层交换机一台&#xff08;实训平台v1.0中cisco vios l2设备&#xff09;3、 二层交换机一台&#xff08;实训平台v1.0中cisco iol switch设备…

Scala实现网页数据采集示例

Scala 可以轻松实现简单的数据采集任务&#xff0c;结合 Akka HTTP&#xff08;高效HTTP客户端&#xff09;和 Jsoup&#xff08;HTML解析库&#xff09;是常见方案。Scala因为受众比较少&#xff0c;而且随着这两年python的热门语言&#xff0c;更让Scala不为人知&#xff0c;…