单链表算法题(四):高级应用篇
单链表算法题四高级应用篇前言前三篇我们分别学习了基础操作移除元素、反转链表、找中点、合并链表进阶技巧链表分割、回文判断、相交链表环与数学环形链表的判断与证明本篇作为系列的最后一篇将讲解链表题目中最具挑战性的一道题——随机链表的复制。这道题被称为链表界的深拷贝它综合了插入节点、指针操作、链表分离等多种技巧是检验链表掌握程度的试金石。终极题目随机链表的复制LeetCode 138. 随机链表的复制给你一个长度为n的链表每个节点包含一个额外增加的随机指针random该指针可以指向链表中的任何节点或空节点。构造这个链表的深拷贝。深拷贝应该正好由n个全新节点组成其中每个新节点的值都设为其对应的原节点的值。新节点的next指针和random指针也都应指向复制链表中的新节点。示例输入head [[7,null],[13,0],[11,4],[10,2],[1,0]] 输出[[7,null],[13,0],[11,4],[10,2],[1,0]] 解释 节点0: val7, randomnull 节点1: val13, random节点0 节点2: val11, random节点4 节点3: val10, random节点2 节点4: val1, random节点0节点定义structNode{intval;structNode*next;structNode*random;};思路分析这道题的难点在于random指针。如果只有next指针我们只需遍历原链表逐个创建新节点并连接即可// 只有 next 指针的简单复制structNode*copyList(structNode*head){structNode*dummymalloc(sizeof(structNode));structNode*taildummy;structNode*curhead;while(cur!NULL){structNode*copymalloc(sizeof(structNode));copy-valcur-val;tail-nextcopy;tailcopy;curcur-next;}returndummy-next;}但有了random指针问题就复杂了复制节点时它的random指向的是原链表的节点但我们需要它指向复制链表中对应的节点。怎么建立原节点 → 复制节点的映射关系呢三种解法对比解法核心思路时间复杂度空间复杂度哈希表法用哈希表存储映射关系O(N)O(N)三步法在原节点后插入复制节点O(N)O(1)哈希表法简单直观但需要额外空间。三步法更巧妙空间复杂度 O(1)是面试官更欣赏的解法。解法一哈希表法直观易懂核心思路第一遍遍历创建所有新节点用哈希表记录原节点 → 复制节点的映射第二遍遍历设置每个复制节点的next和randomstructNode*copyRandomList(structNode*head){if(headNULL){returnNULL;}// 哈希表原节点 → 复制节点// 在 C 语言中我们可以用数组或自己实现哈希表// 这里为了演示使用一个简单的映射数组假设节点地址范围有限// 实际面试中C 可以用 unordered_mapC 需要自己实现// 由于 C 没有内置哈希表这里展示核心逻辑// 实际代码请参考下面的三步法它是 O(1) 空间的returnNULL;}由于 C 语言没有内置哈希表实际面试中如果使用 C 语言更推荐三步法。如果用 C/Java/Python哈希表法也很常用。C 版本供参考classSolution{public:Node*copyRandomList(Node*head){if(!head)returnNULL;unordered_mapNode*,Node*map;Node*curhead;// 第一遍创建所有节点while(cur){map[cur]newNode(cur-val);curcur-next;}// 第二遍设置 next 和 randomcurhead;while(cur){map[cur]-nextmap[cur-next];map[cur]-randommap[cur-random];curcur-next;}returnmap[head];}};复杂度时间 O(N)空间 O(N)解法二三步法最优解⭐⭐⭐这是最巧妙的解法不需要额外空间纯指针操作。核心思想三步走插入复制节点在每个原节点后面插入一个复制节点设置 random 指针复制节点的random指向原节点random的复制节点分离链表将原链表和复制链表分开Step 1在每个原节点后面插入复制节点原链表: A → B → C → NULL 插入后: A → A → B → B → C → C → NULL ↑ ↑ ↑ ↑ ↑ ↑ 原 复 原 复 原 复代码structNode*curhead;while(cur!NULL){structNode*copy(structNode*)malloc(sizeof(structNode));copy-valcur-val;copy-nextcur-next;cur-nextcopy;curcopy-next;}Step 2设置复制节点的 random 指针关键逻辑原节点的random指向某个节点复制节点的random应该指向原节点random的复制节点即copy-random cur-random-next原链表: A → B → C ↓ ↓ ↓ null A B 插入复制节点后: A → A → B → B → C → C ↓ ↓ ↓ ↓ ↓ ↓ null null A A B B ↑ ↑ cur-random-next B 就是 B 的复制节点代码curhead;while(cur!NULL){structNode*copycur-next;if(cur-random!NULL){copy-randomcur-random-next;}else{copy-randomNULL;}curcopy-next;}Step 3分离两个链表将混合链表拆分成两个独立的链表。混合: A → A → B → B → C → C → NULL 分离后: 原链表: A → B → C → NULL 复制链表: A → B → C → NULL代码structNode*newHeadhead-next;structNode*copynewHead;curhead;while(cur!NULL){cur-nextcopy-next;curcur-next;if(cur!NULL){copy-nextcur-next;copycopy-next;}}完整代码structNode*copyRandomList(structNode*head){if(headNULL){returnNULL;}// Step 1: 插入复制节点structNode*curhead;while(cur!NULL){structNode*copy(structNode*)malloc(sizeof(structNode));copy-valcur-val;copy-nextcur-next;cur-nextcopy;curcopy-next;}// Step 2: 设置 random 指针curhead;while(cur!NULL){structNode*copycur-next;if(cur-random!NULL){copy-randomcur-random-next;}else{copy-randomNULL;}curcopy-next;}// Step 3: 分离链表structNode*newHeadhead-next;structNode*copynewHead;curhead;while(cur!NULL){cur-nextcopy-next;curcur-next;if(cur!NULL){copy-nextcur-next;copycopy-next;}}returnnewHead;}图解全过程以一个具体例子来走一遍原链表: [7, null] → [13, 0] → [11, 4] → [10, 2] → [1, 0] ↑ ↑ ↑ ↑ ↑ 索引0 索引1 索引2 索引3 索引4 randomnull random→0 random→4 random→2 random→0 注[val, random_index]Step 1: 插入复制节点[7] → [7] → [13] → [13] → [11] → [11] → [10] → [10] → [1] → [1] → NULL ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 0 0 1 1 2 2 3 3 4 4Step 2: 设置 random原节点 [7] 的 random null → 复制节点 [7] 的 random null ✓ 原节点 [13] 的 random [7] (索引0) → 复制节点 [13] 的 random [7] (索引0) ✓ 原节点 [11] 的 random [1] (索引4) → 复制节点 [11] 的 random [1] (索引4) ✓ 原节点 [10] 的 random [11] (索引2) → 复制节点 [10] 的 random [11] (索引2) ✓ 原节点 [1] 的 random [7] (索引0) → 复制节点 [1] 的 random [7] (索引0) ✓Step 3: 分离原链表: [7] → [13] → [11] → [10] → [1] → NULL 复制链表: [7] → [13] → [11] → [10] → [1] → NULL完美每个复制节点的random都指向了复制链表中对应的节点。为什么三步法能 O(1) 空间关键点在于利用了原链表本身作为存储空间原链表的next指针被暂时征用来存储复制节点复制节点的random可以通过原节点的random 偏移 1 找到不需要额外的哈希表来存储映射关系这就是原地的威力——用链表自身的结构来代替额外数据结构。常见面试追问Q1三步法会破坏原链表吗会。第三步分离后原链表被恢复了next指向恢复所以原链表没有被破坏。但如果中途出错原链表可能被损坏。Q2如果要求不能修改原链表怎么办那就只能用哈希表法了。第一遍遍历原链表建立映射第二遍设置指针。空间复杂度 O(N)。Q3如果 random 指针指向的是原链表中不存在的节点题目保证了random指向链表中的节点或null所以不用担心。Q4三步法中为什么copy-random cur-random-next而不是cur-random因为我们要让复制节点指向复制链表中对应的节点而不是原节点。原节点 A 的 random 指向 B 复制节点 A 的 random 应该指向 BB 的复制节点 B 在哪里在 B 的后面B-next B 所以A-random A-random-next本系列总结四篇博客完整覆盖了单链表的核心算法题篇目题目核心技巧基础操作篇移除链表元素、反转链表、找中点、合并链表哨兵位、三指针、快慢指针进阶技巧篇链表分割、回文链表、相交链表组合技巧、双指针环与数学篇环形链表 I II快慢指针 数学证明高级应用篇随机链表的复制三步法插入 设置 分离链表解题心法回顾整个系列链表题目的核心就这几点1. 画图画图画图 链表题不画图就像闭着眼睛走路。 2. 哨兵位dummy 统一处理头节点省去特殊判断。 3. 快慢指针 环检测、找中点、找倒数第k个一招鲜吃遍天。 4. 三指针 反转链表的基本功。 5. 先保存再修改 修改指针前先保存后继节点防止断链。 6. 注意边界条件 空链表、单节点、头节点、尾节点。结语单链表的算法题到此就全部讲完了。从最基础的增删改查到巧妙的快慢指针再到复杂的随机链表复制每一步都是对指针操作能力的锤炼。记住链表题的答案就在纸上。遇到难题时画个图把指针的变化画清楚代码自然就写出来了。希望这个系列能帮助你在链表题目的道路上少走弯路。如果觉得有收获欢迎点赞收藏最后的小贴士更多的链表题目可以在 LeetCode 和 牛客网 上继续刷保持手感熟能生巧

相关新闻

为什么靠意志力很难?

为什么靠意志力很难?

因为意志力是一种有限资源,而人的行为更多由环境、习惯、情绪和系统共同决定。单纯依靠意志力,相当于每天逼自己打一场战争。第一层:意志力本质是什么? 意志力: 不是“不想做某件事”。 而是:当两个冲突的欲…

2026/8/18 18:52:08 阅读更多 →
转:权力的幻影

转:权力的幻影

个人理解: 如何看待手中权力 一个管理者,若没有权力的加持,他只是普通人,不是超人 制度依赖 VS 人情依赖 复杂的办公室政治 多一点同理心,多一点对方立场的意识,多想想团队中每个个体的欲望和诉求&#xff…

2026/8/18 18:51:07 阅读更多 →
TVA-World生成式具身智能系列研究(9)

TVA-World生成式具身智能系列研究(9)

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的系统级视觉技术框架。它融合深度强化学习(DRL)、卷积神…

2026/8/18 18:51:07 阅读更多 →

最新新闻

RevokeMsgPatcher 防撤回补丁完整攻略:5 分钟上手,微信、QQ、TIM 消息不再凭空消失

RevokeMsgPatcher 防撤回补丁完整攻略:5 分钟上手,微信、QQ、TIM 消息不再凭空消失

RevokeMsgPatcher 防撤回补丁完整攻略:5 分钟上手,微信、QQ、TIM 消息不再凭空消失 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了&…

2026/8/18 19:35:37 阅读更多 →
连连看外挂保姆级教程:Auto-Lianliankan 图像识别秒破,从安装到跑通一次讲清

连连看外挂保姆级教程:Auto-Lianliankan 图像识别秒破,从安装到跑通一次讲清

连连看外挂保姆级教程:Auto-Lianliankan 图像识别秒破,从安装到跑通一次讲清 【免费下载链接】Auto-Lianliankan 基于python图像识别实现的连连看外挂,可实现QQ连连看秒破 项目地址: https://gitcode.com/gh_mirrors/au/Auto-Lianliankan …

2026/8/18 19:35:37 阅读更多 →
Tool / Function Calling 总结

Tool / Function Calling 总结

1. 核心定义1.1 Function CallingFunction Calling(函数调用) 是一种让大语言模型与外部系统进行结构化交互的机制。开发者先向模型声明:有哪些函数可以调用;每个函数的用途;每个函数需要哪些参数;参数的数…

2026/8/18 19:35:37 阅读更多 →
中国行政区划矢量数据免费打包:省市县4级Shapefile,10分钟在QGIS出一张图

中国行政区划矢量数据免费打包:省市县4级Shapefile,10分钟在QGIS出一张图

中国行政区划矢量数据免费打包:省市县4级Shapefile,10分钟在QGIS出一张图 【免费下载链接】ChinaAdminDivisonSHP 中国行政区划矢量图,ESRI Shapefile格式,共四级:国家、省/直辖市、市、区/县。关键字:中国…

2026/8/18 19:35:37 阅读更多 →
从零到交付:如何用 Python 自动化批量处理 DXF 图纸文件(ezdxf 实战全记录)

从零到交付:如何用 Python 自动化批量处理 DXF 图纸文件(ezdxf 实战全记录)

从零到交付:如何用 Python 自动化批量处理 DXF 图纸文件(ezdxf 实战全记录) 【免费下载链接】ezdxf Python interface to DXF 项目地址: https://gitcode.com/gh_mirrors/ez/ezdxf 周一早上九点,你收到一条让人头疼的消息&…

2026/8/18 19:35:37 阅读更多 →
LLM智能体上下文管理:结构化驱逐策略与工程实践

LLM智能体上下文管理:结构化驱逐策略与工程实践

1. 项目概述:当长程智能体遭遇“上下文之困” 最近在折腾LLM驱动的自主智能体(LLM-powered Autonomous Agents)时,一个绕不开的瓶颈越来越清晰地摆在面前:上下文窗口。无论是构建一个能处理复杂工作流的自动化助手&…

2026/8/18 19:34:37 阅读更多 →

日新闻

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 如果你还停留在"看网课 不停暂停 截图 …

2026/8/18 0:00:57 阅读更多 →
思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 你是不是也经历过这种时刻:设计稿里…

2026/8/18 0:00:58 阅读更多 →
华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, …

2026/8/18 0:00:59 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/18 9:15:35 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/18 9:06:28 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/18 9:04:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/17 18:54:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/17 18:55:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/17 18:55:55 阅读更多 →