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

hot100 二叉树的最大深度(104)

本题采用分治递归算法(又称“自底向上深度优先搜索法”)解决二叉树的最大深度计算问题。其核心本质是将全局树高问题拆解为左右子树的局部子问题,利用递归回溯的特性,在叶子节点向根节点回溯的过程中实现深度的累加与最值筛选。当前提供的源码实现了在时间复杂度O(n)和额外空间复杂度O(height)条件下的全局最优树结构检索。

一、 问题本质与数据模型

对于一个给定的二叉树,题目要求的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。

二叉树本身具有天然的递归拓扑结构:每一个非空节点都可以作为一棵独立子树的根节点。因此,求解整棵树的最大深度可以完全等价地转化为一个自底向上的递推模型:

任何一个节点处的最大深度 = max(左子树的最大深度, 右子树的最大深度) + 1

为了破除递归的无限循环,算法引入了“空节点基准退出模型”。当程序深度探测至叶子节点的两侧空指针(null)时,该位置在几何空间上不占据任何高度,表现出基础的边界属性:

  • 命中空节点:返回深度 0。

  • 回溯父节点:将子树反馈的高度加 1,作为当前节点的贡献高度。

这种自底向上的高度吞吐机制,赋予了递归栈类似于“弹簧测力计”的物理特性,每次弹回都能产生准确的局部深度数据。

二、 算法演进对比

在解决二叉树深度检索的问题时,递归分治法在代码优雅度与时空资源的平衡上达到了经典的状态:

解法名称时间复杂度空间复杂度核心原理物理瓶颈 / 缺陷
层序遍历法(BFS 迭代)O(n)O(n)利用队列进行按层扫描,每扫描完一层,深度计数器加 1需要显式借助队列存储当前层的所有节点,在完全二叉树下其最底层宽度可达 n/2,内存开销较大
自顶向下深搜(DFS 携带全局变量)O(n)O(height)从根节点出发向下传递当前深度,并在叶子节点处更新全局最大值需要维护外部全局变量,且代码逻辑相对冗余,不符合纯粹的分治思想
分治递归法(当前解法)O(n)O(height)利用左右子树高度的确定性,自底向上严格收敛,代码极度精简极度倾斜的树(如链表状二叉树)会导致递归栈深度退化为 O(n)

三、 核心分支控制逻辑与决策证明

当前源码的控制流完全依赖于函数入口的边界防护以及自底向上的数据归纳,其内部决策分支证明如下:

1. 基准出口分支:if (root == null)

  • 执行:直接返回0

  • 物理意义:当前坐标已越过叶子节点,到达不存在的空子树,检索流程在该分支触底并启动回溯。

2. 局部探底分支:int lRes = maxDepth(root.left);int rRes = maxDepth(root.right);

  • 执行:分别向左、右子节点派发相同的求解任务。

  • 数学证明:基于数学归纳法,假设当前节点的左右子树已经正确计算出了它们各自的最大深度分别为lResrRes

3. 深度归纳合并:return Math.max(lRes, rRes) + 1;

  • 执行:取左右子树深度较大者,加1后返回给上一层。

  • 数学证明:从当前节点出发向下的最长路径,必然通过它“更高的一侧”子树。因此,当前子树的整体高度等于高子树的高度加上当前节点自身所占的一层物理高度(即+ 1)。

  • 结论:该返回值完美契合二叉树深度的递归定义,确保了数据向上推导的精准性。

四、 算法执行状态机步进示例

以输入二叉树root = [3, 9, 20, null, null, 15, 7](规模 5 个有效节点)为例,递归调用栈的状态机演进及回溯过程如下表所示:

步骤当前处理节点触发的分支动作接收到的子节点返回值执行的核心合并决策局部栈反馈高度说明
1节点 9探测左右子节点左=null (0), 右=null (0)Math.max(0, 0) + 1节点 9 处的局部高度为1,向上传递
2节点 15探测左右子节点左=null (0), 右=null (0)Math.max(0, 0) + 1节点 15 处的局部高度为1,向上传递
3节点 7探测左右子节点左=null (0), 右=null (0)Math.max(0, 0) + 1节点 7 处的局部高度为1,向上传递
4节点 20接收 15 和 7 的反馈左=15 (1), 右=7 (1)Math.max(1, 1) + 1节点 20 处的局部高度为2,向上传递
5节点 3 (根)接收 9 和 20 的反馈左=9 (1), 右=20 (2)Math.max(1, 2) + 1全局高度锁定为3,程序最终返回

五、 源码实现

class Solution { public int maxDepth(TreeNode root) { // 边界安全检查:若当前节点为空,说明已越过叶子节点,高度贡献为 0 if (root == null) { return 0; } // 递归获取左子树的最大深度 int lRes = maxDepth(root.left); // 递归获取右子树的最大深度 int rRes = maxDepth(root.right); // 核心决策:当前节点的最大深度等于左右子树中较大深度加 1(当前节点自身高度) return Math.max(lRes, rRes) + 1; } }

六、 复杂度分析

1. 时间复杂度:O(n)

  • 分析:算法采用标准的深度优先遍历模式。在递归执行过程中,二叉树中的每一个节点TreeNode都会且仅会被访问一次(进栈一次,出栈一次)。

  • 结论:总的操作次数与二叉树的节点总数n呈严格的线性正比关系,即时间复杂度为O(n)

2. 空间复杂度:O(height)

  • 分析:该算法没有申请任何额外的外部数据结构,其空间消耗完全取决于递归调用时系统开辟的函数隐式栈深度。隐式栈的最大深度等于二叉树的最大高度height

    • 最坏情况下(二叉树退化为单链表结构),树高height等于n,空间复杂度退化为O(n)

    • 最好情况下(二叉树为完全二叉树或平衡二叉树),树高height严格等于log n,空间复杂度为O(log n)

  • 结论:内存空间消耗在通用状态下定义为常数阶基础上的拓扑层级消耗,即O(height)

http://www.jsqmd.com/news/1159743/

相关文章:

  • Kimi K2.5:面向办公与开发的智能操作系统解析
  • 环氧树脂固化变形仿真:3种本构模型对比与Kamal方程参数校准
  • 海王IM全新升级|三方聊天软件源码部署,支持多端同步运营
  • Python程序打包终极指南:一键生成可执行文件的完整教程
  • FP4注意力内核解析:低精度计算如何优化视频AI推理性能
  • 从Demo到生产级:企业AI Agent平台架构设计与工程实践
  • 从“凭经验“到“靠系统“:让40%的投后风险在立项前就消失
  • Linux内核fork系统调用深度解析:从汇编到页表映射的17个内存动作
  • 板书设计太随意?优秀教师都在遵循的3个视觉原则
  • 终极IDM激活解决方案:3分钟永久告别试用期弹窗
  • PMP考点怎么选?看完这篇不纠结!
  • 4家主流代理记账公司评测:合规与服务实力对比 - 奔跑123
  • ROS 2 Galactic 多传感器软同步:message_filters 与 ApproximateTime 策略实测
  • Spatial-Agent:地理分析工作流的范式迁移与GAWD实践
  • AI 电动汽车驱动控制器智能功率器件完整选型方案
  • 八路抢答器硬件设计:从74LS148到CD4511的3种锁存与显示方案对比
  • 猫抓浏览器扩展:5分钟掌握网页资源智能捕获的终极指南
  • 沉浸式体验呼伦贝尔6天5晚纯玩小包团领略绝美草原风光
  • GPMall 电商项目深度评测:SpringBoot+Dubbo 微服务架构的 3 大优势与 2 个待优化点
  • 从零构建AI智能体:基于Coze与Dify的实战开发全流程指南
  • Web自动化验证码识别:从OCR到深度学习的完整解决方案
  • ASIC/FPGA/SoC 设计流程对比:从RTL到GDSII的7个核心阶段差异详解
  • 5分钟完成黑苹果配置:OpCore Simplify终极解决方案
  • ChatGPT Plus订阅成功率提升210%的实战策略:基于3726份订阅日志分析的7个关键节点优化清单
  • 构建基本shell脚本
  • 扩展卡尔曼滤波 (EKF) 实战:处理 3 类非线性系统的状态估计
  • Anthropic拟全面封禁地下通道
  • Shell脚本精读 · S12-02 | 语法检查与 ShellCheck:静态发现问题
  • ClawdBot:轻量级自动化代理框架实现7×24数字分身
  • 大模型自检机制:提升LLM输出可靠性的工程实践