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

LeetCode 148. 排序链表:归并排序详解

拆解 LeetCode 中等难度题目「148. 排序链表」这道题核心考察链表的归并排序是链表操作与排序算法结合的经典题型也是面试中高频出现的考点。本文会从题目分析、解题思路、代码拆解到注意事项一步步帮大家搞懂这道题新手也能轻松跟上。一、题目回顾题目要求给你链表的头结点 head 请将其按升序排列并返回排序后的链表。补充说明链表中节点的数目范围是 [0, 5 * 10⁴]-10⁵ ≤ Node.val ≤ 10⁵进阶要求你可以在 O(n log n) 时间复杂度和常数级空间复杂度下对链表进行排序吗本文解法将满足这一要求二、解题思路为什么选择归并排序首先思考链表排序和数组排序有什么区别数组可以用快速排序随机访问效率高但链表的随机访问效率低O(n)而归并排序的核心是「分治合并」刚好适配链表的特性——分治时无需随机访问合并时只需调整指针且时间复杂度天然是 O(n log n)完美契合题目要求。归并排序的整体思路链表适配版分将链表从中间分成左右两个子链表递归拆分直到每个子链表只包含一个节点单个节点本身就是有序的治将两个有序的子链表合并成一个有序的链表合递归合并所有子链表最终得到完整的有序链表。关键难点如何找到链表的中间节点分治的核心、如何高效合并两个有序链表。三、完整代码TypeScript 版先贴出完整可运行代码后续逐部分拆解大家可以先整体感知classListNode{val:numbernext:ListNode|nullconstructor(val?:number,next?:ListNode|null){this.val(valundefined?0:val)this.next(nextundefined?null:next)}}functionsortList(head:ListNode|null):ListNode|null{// 边界处理空链表直接返回if(headnull){returnnull;}// 1. 找到链表中间节点二分核心constfindMid(left:ListNode,right:ListNode|null):ListNode{if(leftright){returnleft;}// 快慢指针慢指针走1步快指针走2步快指针到尾时慢指针在中间letslow:ListNode|null|undefinedleft;letfast:ListNode|null|undefinedleft.next;// 快指针不越界right是区间边界不包含while(fast!nullfast?.next!null){slowslow.next!;fastfast.next?.next;}returnslow;};// 2. 递归分治合并constdfs(left:ListNode|null,right:ListNode|null):ListNode|null{if(leftnull){returnnull;}// 单个节点直接返回递归终止条件if(leftright){returnleft;}// 找中间节点拆分链表constmidfindMid(left,right);constrightHeadmid.next;// 右子链表的头节点mid.nextnull;// 切断左右子链表避免循环// 递归拆分左、右子链表lettemp_1dfs(left,mid);lettemp_2dfs(rightHead,right);// 合并两个有序子链表returnmergeTwoLists(temp_1,temp_2);};// 3. 合并两个有序链表辅助函数constmergeTwoLists(l1:ListNode|null,l2:ListNode|null):ListNode|null{constdummyHeadnewListNode(0);// 虚拟头节点简化合并逻辑lettempdummyHead;// 双指针遍历两个链表按值大小拼接while(l1!nulll2!null){if(l1.vall2.val){temp.nextl1;l1l1.next;}else{temp.nextl2;l2l2.next;}temptemp.next;// 移动指针}// 拼接剩余节点其中一个链表可能已遍历完temp.nextl1!null?l1:l2;returndummyHead.next;// 返回合并后的链表头};// 调用递归函数初始区间头节点到null右边界不包含returndfs(head,null);};四、代码逐部分拆解1. 链表节点类ListNode题目已给出节点类的定义核心是两个属性val节点存储的值number类型next指向后续节点的指针可能为null代表链表尾。构造函数做了默认值处理val默认0next默认null避免传入undefined时报错。2. 边界处理if(headnull){returnnull;}当输入链表为空时直接返回null避免后续递归出现异常这是所有链表题的常规操作。3. 找到链表中间节点findMid函数这是分治的核心采用「快慢指针法」效率比遍历计数找中间节点更高O(n/2) 时间。核心逻辑慢指针slow初始指向left每次走1步快指针fast初始指向left.next每次走2步当快指针无法再走2步fast null 或 fast.next null时慢指针刚好指向链表的中间节点。注意函数参数中的right是「区间边界不包含」比如初始调用时right为null代表拆分到链表末尾。4. 递归分治dfs函数dfs函数的作用是「拆分链表合并链表」递归终止条件是当left right时说明当前子链表只有一个节点直接返回单个节点有序。关键步骤调用findMid找到中间节点mid将mid.next赋值给rightHead右子链表的头并将mid.next设为null切断左右子链表避免递归时循环遍历递归调用dfs分别处理左子链表left到mid和右子链表rightHead到right调用mergeTwoLists将两个有序的子链表合并返回合并后的链表头。5. 合并两个有序链表mergeTwoLists函数这是归并排序的「治」环节也是链表操作的经典场景采用「虚拟头节点双指针」实现。核心逻辑创建虚拟头节点dummyHead值为0无实际意义用于简化链表拼接逻辑无需单独处理头节点temp指针指向dummyHead用于遍历拼接新链表双指针l1、l2分别遍历两个有序子链表每次将值较小的节点拼接到temp.next然后移动对应指针当其中一个链表遍历完后将另一个链表的剩余节点直接拼接到temp.next剩余节点已有序返回dummyHead.next即合并后的有序链表头。6. 主函数调用returndfs(head,null);初始调用dfs时左边界为head链表头右边界为null不包含即链表尾开启递归分治与合并。五、关键注意事项避坑点拆分链表时必须将mid.next设为null否则左右子链表会相连递归时会陷入死循环快慢指针的初始位置fast要比slow超前一步left.next否则当链表长度为2时会无法拆分比如1→2slow和fast都指向1无法分成[1]和[2]合并链表时虚拟头节点的使用是关键能避免单独判断头节点的麻烦提升代码简洁度递归终止条件left right单个节点否则会无限递归导致栈溢出。六、复杂度分析满足进阶要求时间复杂度O(n log n)归并排序的标准时间复杂度分治环节是O(log n)层每一层的合并环节是O(n)整体为O(n log n)空间复杂度O(log n)递归调用栈的深度为O(log n)分治的层数没有使用额外的数组或哈希表满足常数级空间的进阶要求若不考虑递归栈空间复杂度为O(1)。七、总结LeetCode 148.排序链表的核心是「链表的归并排序」核心难点在于「找中间节点」和「合并有序链表」而快慢指针和虚拟头节点是解决这两个难点的关键技巧。这道题的价值在于它不仅考察了链表的基本操作还融合了归并排序的分治思想是面试中考察「链表排序」的典型代表。建议大家多动手调试代码重点理解拆分链表时的指针切断、合并链表时的双指针移动掌握后能轻松应对同类链表排序问题。

相关文章:

LeetCode 148. 排序链表:归并排序详解

拆解 LeetCode 中等难度题目「148. 排序链表」,这道题核心考察链表的归并排序,是链表操作与排序算法结合的经典题型,也是面试中高频出现的考点。本文会从题目分析、解题思路、代码拆解到注意事项,一步步帮大家搞懂这道题&#xff…...

淘宝商品详情字段解析:SKU、价格、库存接口全梳理

在电商数据采集、竞品分析、价格监控等场景中,淘宝商品详情数据是核心资产。本文聚焦淘宝开放平台商品详情接口的SKU、价格、库存三大核心字段,从接口调用到字段解析,再到实战代码与避坑指南,提供一套完整的技术方案,助…...

算法设计与分析-习题4.3

目录 1.在你的计算机上实现一个要求生成 25 个元素组成的集合的全部排列的算法是否现实?如果是生成该集合的所有子集呢? 2.使用下面的方法生成{1,2,3,4}的全部排列: a.从底向上的最小变化算法。 b. Johnson-Trotter算法。 ​…...

一篇看懂:进程、服务、启动项、计划任务到底是什么?

很多刚接触电脑、运维、Windows / 服务器的朋友,都会被这四个词绕晕:进程、服务、启动项、计划任务。它们长得像、功能像、还经常一起出现,但职责完全不同。这篇用最通俗的话,帮你一次性分清。一、进程(Process&#x…...

sdut-程序设计基础Ⅰ-实验7-函数(函数题)

6-1 sdut-C语言实验-计算组合数分数 10作者 马新娟单位 山东理工大学计算组合数。C(n,m),表示从n个数中选择m个的组合数。 计算公式如下: 若:m0,C(n,m)1 否则, 若 n1,C(n,m)1 否则,若mn,C(n,m)1…...

为2026年营销活动找富士山素材,这五类站点的筛选顺序很重要

作为一名市场专员,上周我接到了一个有些紧急的任务:为公司一个重要的日式主题营销活动设计主视觉,并在当晚拿出第一版概念稿。核心元素是富士山,但要求风格现代、简约,避免使用那些随处可见的游客照或过时的插画。问题…...

在 Kata Containers 中编译支持 eBPF 的 Guest Kernel 并验证生效

此前在 8 月份因项目需求,我对 Kata 容器进行了调研,并在 CentOS 上部署了单机版 Kata 环境。当时受限于进度,仅完成基础环境搭建。近期我重新开始探索 eBPF 在 Kata 容器中的支持与适配情况,于是有了这篇文章。后续我还会输出 Ka…...

51单片机驱动共阴极数码管显示0~9

文章目录 概要 硬件设计 软件设计 编译下载 小结 概要 项目采用共阴极单支数码管作为显示器件,通过单片机I/O口输出段选信号控制数码管段亮灭,配合延时函数实现数字0~9每隔1秒自动加1,并循环往复显示的功能。 硬件设计 1. 核心器件 …...

模拟1688商品详情的Python API实现,返回符合风格的JSON数据

该文件包含两个模拟商品数据,结构完整覆盖以下核心字段:商品基础信息:商品ID、标题、价格(含原价与现价)、库存量商品描述:富文本描述内容视觉展示:多图链接列表(主图详情图&#xf…...

Google Banana pro 画卡通信息图

提示词:[System / Prompt]You are an illustration assistant specialized in creating hand-drawn cartoon-style infographics. Follow all rules below strictly and without deviation.🎨 STYLE RULES(风格规则)Use a pure ha…...

算力焦虑终结?揭秘GPU云服务器的民主化之路

从算力焦虑到算力民主:一份GPU云服务器的深度观察 在大模型参数规模朝着万亿单位迈进之时,于文生视频应用在短短几秒内所消耗的算力等同于传统应用数月用量之际,一个无法争议的事实呈现眼前:算力,特别是 GPU 算力&…...

Spring AI + RAG + 向量库 10 道模拟面试

文章目录1. 什么是 Spring AI?它解决什么问题?2. Spring AI 的核心组件有哪些?3. Spring AI 和 LangChain 的区别?4. 什么是 RAG?为什么要用 RAG?5. RAG 的完整流程是什么?6. 为什么要用向量数据…...

Obsidian笔记记录与Gitee云存储

Obsidian下载 首先下载ObsidianObsidian - 磨砺你的思维,下载完成后打开会弹出本地仓库创建的提示 每个仓库都是一个相对独立的空间,我们的笔记和插件都存放在里面,如核心插件的插入模板的模板文件夹和第三方插件都是各仓库独立,…...

Dev-C++中项目类型如何选择?

在Dev-C中选择项目类型时,主要根据开发需求来决定。以下是常见选项及其适用场景:1. 控制台程序(Console Application)用途:适用于命令行界面的程序(如算法练习、数据处理等)。特点:运…...

破解密码.

1.开启虚拟机,快速点击鼠标,用上下键选择第二个选项2.然后按E键3.按左右上下键,将光标移到”quiet"后边,4.输入“rd.break"5.按”ctrlx或F10“,进入该界面6.输入此代码后设置密码(不要设置和之前…...

Chrome DevTools在Agent编程工具上的安装

1.Cursor上安装vscode打开Agent Settings{"mcpServers": {"chrome-devtools": {"command": "npx","args": ["chrome-devtools-mcplatest"]}} }claude code和codex在CLI中# Claude Codeclaude mcp add chrome-devt…...

CMD和PowerShell在激活conda环境中遇到的问题

问题引入近日在部署一个agent项目中遇到了激活虚拟环境的问题,现在的IDE默认终端一般是powershell,用conda命令创建、删除环境没啥问题,但是就是激活进入不了。而平时我用conda命令一般用cmd终端(其实之前一直没注意cmd和powershe…...

HakcMyVM-Darkside

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.2.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-15 03:46 EDT Nmap scan report for darkside (192.168.2.19) Host is up (0.00023s latency). MAC Address: 08:00:27:3B:49:15 (PCS Systemt…...

基于C语言的轻量级在线商城服务端设计与实现

在当前以Java、Go和Python为主导的电商后端技术生态中,使用C语言构建Web服务似乎显得格格不入。然而,在资源受限环境或对性能有极致追求的场景下,C语言的价值不容忽视。它能够提供对内存和系统调用的精确控制,避免高级语言运行时带…...

欧姆龙CP1H与台达VFD - M变频器的MODBUS RTU通讯实战

欧姆龙CP1H的MODBUS RTU简易主站通讯,通过CP1W-CIF11板与台达VFD-M变频器进行。PLC程序进行轮询通讯,正常情况下只进行读操作,当修改频率或者操作启停命令时,才进行写操作,写操作完成后自动移除。 从而起到保护从站变频…...

从能跑到跑得快:一次大模型硬件加速的工程实践

从能跑到跑得快:一次大模型硬件加速的工程实践 写大模型应用时,很多团队最先遇到的问题不是“模型会不会答”,而是“模型为什么这么慢”。 一套模型在开发阶段能跑起来,和它能在线上稳定、低延迟、可并发地服务用户,是…...

【第二周】RAG与Agent实战13:通用提示词模板 (PromptTemplate)

在之前我们直接将字符串传给模型: model.invoke("帮我写一首诗")这种写法叫做 Zero-shot(零样本) 提示。但在实际应用中,我们需要动态地替换提示词中的内容(比如用户的名字、查询的问题、文档的片段&#xf…...

基于VirtualLab Fusion的复合光源仿真

摘要能够在一个系统中包含多个光源是许多应用的基础,如成像或照明。VirtualLabFusion提供了解决这类问题的高级选项。在本文档中,我们简要概述了如何设置复合光源,并给出了几个仿真示例。概览复合光源可以:包含任意数量的主光源。…...

快速清理手机QQ大量占用的存储空间

快速清理手机QQ大量占用的存储空间 众所周知,手机QQ随着使用会占据越来越多的磁盘空间,甚至多达上百GB。 在面对如此大量的存储数据时,无论是QQ自带的清理工具,还是手机管家之类系统自带的清理工具,其实往往都表现很糟…...

LITESTAR 4D 新模块:Sport Plus-运动场高级照明管理模块

您是否想要一个程序以自动,简单和快速的方式设计运动区域的照明?如果是这样,LITESTAR 4D Litecalc 运动区的额外模块 Sport Plus 是理想的解决方案。区域和高桅杆定义运动区域和高杆定义中可以设定以下内容:1. 运动设施的一般区域…...

使用OpenClaw+Skill自动发布微信公众号文章

一、OpenClaw 介绍 OpenClaw 是一款‌本地优先、可自托管的AI自动化代理工具‌,可以运行在你自己的电脑上,通过各种聊天工具(飞书、QQ、Telegram 等)与你对话,帮你完成各种任务。 1.1 什么是 OpenClaw? 你可…...

受激发射损耗(STED)显微镜原理

摘要受激发射损耗(STED)显微镜描述了一种常用的技术,以实现在生物应用的超分辨率。在这种方法中,两束激光—一束正常,一束转变成甜甜圈模式—被叠加到荧光样品上。通过使用荧光过程的发射和损耗以及利用由此产生的饱和效应,与通常…...

电工操作证报名照片太大?1分钟学会照片压缩技巧

报考电工操作证,作为从事电力作业、设备维修、线路安装的一线人员,日常工作强度大、时间零散,报名办证时照片上传常常成为麻烦事。很多电工朋友已经按要求拍好证件照,清晰度、着装、背景都没问题,就因为照片文件体积太…...

在虚拟机中安装一个linux操作系统

...

ch4_1

//--------------------- // ch4_1.cpp //--------------------- #include<iostream> using namespace std; //--------------------- int main(){int i1,sum0; //初始化while(i<100){sumsumi;ii1;}cout<<"sum "<<sum<<endl; }//---…...