首页/新闻资讯/正文详情

【二叉树-10】114.二叉树展开为链表

发布时间:2026/9/26 18:44:34 来源:云帆数科 栏目:资讯中心
【二叉树-10】114.二叉树展开为链表
题目描述给你二叉树的根结点root请你将它展开为一个单链表展开后的单链表应该同样使用TreeNode其中right子指针指向链表中下一个结点而左子指针始终为null。展开后的单链表应该与二叉树 先序遍历 顺序相同。示例 1输入root [1,2,5,3,4,null,6]输出[1,null,2,null,3,null,4,null,5,null,6]示例 2输入root []输出[]示例 3输入root [0]输出[0]解题思路方法一递归后序遍历核心思路对于任意节点root递归展开左子树得到左子树链表递归展开右子树得到右子树链表拼接把左子树链表接到root-right把右子树链表接到左子树链表的末尾root-left nullptr具体过程示例1 / \ 2 5 / \ \ 3 4 6 第1步: 递归展开左子树(2) 2 \ 3 \ 4 第2步: 递归展开右子树(5) 5 \ 6 第3步: 拼接 1 \ 2 \ 3 \ 4 \ 5 \ 6 ✅代码实现写法1后序遍历推荐class Solution { public: void flatten(TreeNode* root) { if (root nullptr) return; // 先递归展开左右子树 flatten(root-left); flatten(root-right); // 保存右子树 TreeNode* right root-right; // 把左子树接到右边 root-right root-left; root-left nullptr; // 找到当前右子树的末尾接上原来的右子树 TreeNode* curr root; while (curr-right ! nullptr) { curr curr-right; } curr-right right; } };写法2前序遍历用栈class Solution { public: void flatten(TreeNode* root) { if (root nullptr) return; stackTreeNode* stk; stk.push(root); TreeNode* prev nullptr; while (!stk.empty()) { TreeNode* curr stk.top(); stk.pop(); if (prev ! nullptr) { prev-right curr; prev-left nullptr; } // 先压右再压左保证左先出栈 if (curr-right) stk.push(curr-right); if (curr-left) stk.push(curr-left); prev curr; } } };复杂度分析写法1后序递归维度复杂度说明时间复杂度O(n²)每次找右子树末尾需要 O(n)空间复杂度O(h)递归栈深度问题找右子树末尾的while循环导致 O(n²)。写法2前序栈维度复杂度说明时间复杂度O(n)每个节点入栈出栈各一次空间复杂度O(n)栈最多存储 n 个节点关键细节1. 为什么后序递归全局 prev能 O(n)遍历顺序右 → 左 → 根每次处理当前节点时prev已经指向了前序遍历中的下一个节点直接把root-right prev即可不需要找末尾2. 图解后序递归全局 prev1 / \ 2 5 / \ \ 3 4 6 遍历顺序: 6 → 5 → 4 → 3 → 2 → 1 处理6: prevnull, 6-rightnull, prev6 处理5: prev6, 5-right6, prev5 处理4: prev5, 4-right5, prev4 处理3: prev4, 3-right4, prev3 处理2: prev3, 2-right3, prev2 处理1: prev2, 1-right2, prev1 结果: 1 → 2 → 3 → 4 → 5 → 6 ✅3. 为什么前序栈要先压右再压左因为栈是后进先出先压右右在栈底再压左左在栈顶弹出时先弹出左符合前序顺序方法二找左子树的最右节点(原地算法)核心思路对于每个节点root如果root-left nullptr直接跳到root-right如果root-left ! nullptr找到左子树的最右节点前序前驱把root-right接到这个最右节点的右边把root-left移到root-rightroot-left nullptr继续处理新的root-right具体过程示例1 / \ 2 5 / \ \ 3 4 6 处理节点1: 左子树是2找左子树的最右节点 → 4 把 1-right (5) 接到 4-right 把 1-left (2) 移到 1-right 1-left nullptr 1 \ 2 / \ 3 4 \ 5 \ 6 处理节点2: 左子树是3找左子树的最右节点 → 3 把 2-right (4) 接到 3-right 把 2-left (3) 移到 2-right 2-left nullptr 1 \ 2 \ 3 \ 4 \ 5 \ 6 继续处理3、4、5、6最终得到: 1 → 2 → 3 → 4 → 5 → 6 ✅代码实现class Solution { public: void flatten(TreeNode* root) { TreeNode* curr root; while (curr ! nullptr) { if (curr-left ! nullptr) { // 找到左子树的最右节点前序前驱 TreeNode* prev curr-left; while (prev-right ! nullptr) { prev prev-right; } // 把当前节点的右子树接到前驱的右边 prev-right curr-right; // 把左子树移到右边 curr-right curr-left; curr-left nullptr; } // 继续处理下一个节点 curr curr-right; } } };复杂度分析维度复杂度说明时间复杂度O(n)每个节点最多被访问两次空间复杂度O(1)只用了几个指针为什么是 O(n)外层while遍历每个节点一次内层while找最右节点但每条边最多被走两次总操作次数 O(n)关键细节1. 为什么找左子树的最右节点因为前序遍历的顺序是根 → 左子树 → 右子树左子树的最后一个节点最右节点就是右子树的前驱把右子树接到它后面正好符合前序顺序2. 为什么curr curr-right不会死循环每次处理完当前节点后curr-right指向了左子树的根curr-left被置空所以curr curr-right会走到左子树的根继续处理最终会走到nullptr循环结束3. 为什么时间复杂度是 O(n) 而不是 O(n²)虽然内层while看起来可能很耗时但每条边最多被走两次一次找最右节点一次遍历总操作次数与节点数成正比所以是 O(n)三种方法对比方法时间复杂度空间复杂度是否原地推荐度后序递归全局 prevO(n)O(h)❌ 递归栈⭐⭐⭐⭐⭐前序栈O(n)O(n)❌ 栈⭐⭐⭐⭐原地算法O(n)O(1)✅原地⭐⭐⭐⭐⭐总结要点说明核心思想找左子树最右节点把右子树接过去关键操作prev-right curr-right; curr-right curr-left; curr-left nullptr时间复杂度O(n)空间复杂度O(1)

相关推荐

无未来函数才是关键:股票指标公式可靠性指南
无未来函数才是关键:股票指标公式可靠性指南

"黑马来临 相当不错的公式 无未来函数"——这个标题我在各大股软论坛里见过太多次了。说实话,刚开始研究指标公式那两年,我也被这类标题反复吸引,下载了一堆"神公式",回测历史K线时个个都像神仙,可… · 2026/9/26 18:44:27

腾讯WorkBuddy三周实测:AI工作台如何用技能包与Agent重塑办公流程
腾讯WorkBuddy三周实测:AI工作台如何用技能包与Agent重塑办公流程

1. 先从被问烂的问题说起:WorkBuddy 是 CodeBuddy 的办公版吗1.1 产品定位:一个带技能包的 AI 工作台我本来对"AI 办公助手"这类东西有点免疫。市面上打着这个旗号的产品太多了,装完、点开、玩两分钟,最后基本都躺在 Do… · 2026/9/26 18:44:13

Agent从Demo到生产:真正缺的是工程化能力
Agent从Demo到生产:真正缺的是工程化能力

从去年开始,我陆陆续续帮几家企业把自己的 Agent 项目从 Demo 推向生产,有的走到了内部工具阶段,有的死在了灰度测试。一个让我印象很深的规律是:几乎每个团队都以为自己的瓶颈是模型能力不够,但真正卡住上线的&#x… · 2026/9/26 18:44:06

校园小商品交易系统数据库实战:从建表到事务的完整链路
校园小商品交易系统数据库实战:从建表到事务的完整链路

简介:这份PDF文档是一份数据库课程设计报告,主题为“校园小商品交易系统”,面向高校计算机相关专业学生及数据库初学者,帮助其完成从需求分析到界面设计的完整项目实践。文档共1个PDF文件,压缩包约633KB,内… · 2026/9/26 19:21:25

自建CRM系统实践:从需求分析到数据迁移的完整避坑指南
自建CRM系统实践:从需求分析到数据迁移的完整避坑指南

DeskcommCRM这个项目,是我在上一家公司从0到1主导建设的一套企业客户关系管理系统。项目名是内部起名阶段定的,Desk代表工位,comm是communication的缩写,合在一起就是想表达“坐在工位上就能把客户沟通和业务推进全部管起来”。现… · 2026/9/26 19:21:25

智能工厂四层架构落地指南:技术、系统、数据、应用架构拆解与避坑
智能工厂四层架构落地指南:技术、系统、数据、应用架构拆解与避坑

简介:这份PPT资料面向智能制造规划人员、工厂信息化负责人及数字化转型从业者,系统梳理智能工厂从顶层设计到落地实施的完整方法论。内容围绕总体设计方法、业务调研与分析、智能工厂总体规划、建设路线规划及系统初步设计展开,重点覆盖业务架… · 2026/9/26 19:21:25

电力智能巡检机器人技术方案:室外室内导航选型与部署避坑指南
电力智能巡检机器人技术方案:室外室内导航选型与部署避坑指南

简介:这份PPT资料聚焦电力行业室外与室内智能巡检机器人,面向电力运维人员、变电巡检技术人员及智能装备学习者,帮助理解传统人工巡检效率低、准确性不足、恶劣环境下安全风险高等痛点的智能化解决路径。内容覆盖输电、变电、配电及地下管廊隧… · 2026/9/26 19:21:19

SQL数据库图书管理系统课程设计:从建库到借阅闭环的完整实现
SQL数据库图书管理系统课程设计:从建库到借阅闭环的完整实现

简介:这份SQL数据库图书管理系统课程设计文档,面向高校计算机相关专业学生及数据库初学者,用于完成数据库应用技术课程的课程设计任务。文档围绕图书管理系统的完整设计流程展开,涵盖系统分析、E-R图绘制、数据字典、关系模式定义… · 2026/9/26 19:21:19

反射式光学系统结构设计:从Zemax建模到可加工图纸的完整链路
反射式光学系统结构设计:从Zemax建模到可加工图纸的完整链路

简介:这份文档面向光学设计初学者与工程技术人员,围绕Zemax软件讲解反射式系统的结构设计方法,帮助读者理解如何用反射镜替代透镜完成光线聚焦与像差校正。内容从球面与非球面反射镜的定义入手,系统梳理牛顿望远镜、经典卡塞格林、… · 2026/9/26 19:21:19

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码