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

LeetCode 104:二叉树的最大深度 | DFS

LeetCode 104:二叉树的最大深度 | DFS

一、题目详解

1.1 题目描述

LeetCode 104:二叉树的最大深度(Maximum Depth of Binary Tree)

给定一个二叉树root,返回其最大深度。

二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。

难度:Easy

示例 1:

输入:root = [3,9,20,null,null,15,7] 输出:3

示例 2:

输入:root = [1,null,2] 输出:2

1.2 题目分析

这是一道经典的树遍历问题,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来解决。

叶子节点:没有子节点的节点(左右子节点都为空)。


二、算法实现

2.1 DFS递归实现

def maxDepth(root): if not root: return 0 # 递归计算左右子树深度,取较大值加1(当前节点) left_depth = maxDepth(root.left) right_depth = maxDepth(root.right) return 1 + max(left_depth, right_depth)

递归思路解析:

  1. 如果当前节点为空,深度为0
  2. 递归计算左子树深度
  3. 递归计算右子树深度
  4. 当前节点的深度 = 1 + max(左子树深度, 右子树深度)

2.2 BFS实现

from collections import deque def maxDepth_bfs(root): if not root: return 0 depth = 0 queue = deque([root]) while queue: depth += 1 size = len(queue) for _ in range(size): node = queue.popleft() if node.left: queue.append(node.left) if node.right: queue.append(node.right) return depth

BFS思路解析:

  1. 初始化队列,将根节点入队
  2. 每处理完一层节点,深度加1
  3. 将当前层所有节点的子节点入队
  4. 重复直到队列为空

2.3 迭代DFS实现(使用栈)

def maxDepth_iterative(root): if not root: return 0 max_depth = 0 stack = [(root, 1)] while stack: node, depth = stack.pop() max_depth = max(max_depth, depth) if node.right: stack.append((node.right, depth + 1)) if node.left: stack.append((node.left, depth + 1)) return max_depth

三、复杂度分析

3.1 递归DFS

  • 时间复杂度:O(n),每个节点访问一次
  • 空间复杂度:O(h),递归调用栈的深度
    • 最好情况(平衡树):O(log n)
    • 最坏情况(链式树):O(n)

3.2 BFS

  • 时间复杂度:O(n),每个节点入队出队一次
  • 空间复杂度:O(n),队列最多存储 n/2 个节点

3.3 迭代DFS

  • 时间复杂度:O(n),每个节点入栈出栈一次
  • 空间复杂度:O(h),栈的最大深度

四、边界情况讨论

4.1 空树

root = None # 输出:0

4.2 单节点树

root = TreeNode(1) # 输出:1

4.3 完全二叉树

# 1 # / \ # 2 3 # / \ / \ # 4 5 6 7 # 最大深度:3

4.4 链式树(只有左子树)

# 1 # / # 2 # / # 3 # 最大深度:3

五、相关扩展问题

5.1 最小深度

def minDepth(root): if not root: return 0 # 如果只有左子树 if not root.right: return 1 + minDepth(root.left) # 如果只有右子树 if not root.left: return 1 + minDepth(root.right) return 1 + min(minDepth(root.left), minDepth(root.right))

5.2 判断平衡二叉树

def isBalanced(root): def check(node): if not node: return 0 left = check(node.left) if left == -1: return -1 right = check(node.right) if right == -1: return -1 if abs(left - right) > 1: return -1 return 1 + max(left, right) return check(root) != -1

5.3 二叉树的直径

def diameterOfBinaryTree(root): max_diameter = 0 def depth(node): nonlocal max_diameter if not node: return 0 left = depth(node.left) right = depth(node.right) # 更新直径 max_diameter = max(max_diameter, left + right) return 1 + max(left, right) depth(root) return max_diameter

六、总结

6.1 核心要点

要点说明
递归DFS代码简洁,易于理解
BFS使用队列,按层计数
迭代DFS使用栈,模拟递归
时间复杂度三种方法都是O(n)

6.2 方法对比

方法优点缺点
递归DFS代码最简洁可能栈溢出(极端情况)
BFS层次清晰空间复杂度较高
迭代DFS避免栈溢出代码稍复杂

6.3 扩展思考

  1. 如何计算二叉树的平均深度?
  2. 如何找到二叉树中距离最远的两个节点?
  3. 最大深度问题在实际应用中有什么意义?

参考资料:

  • LeetCode 104 题解
  • 二叉树深度
http://www.cnnetsun.cn/news/2608673.html

相关文章:

  • ChatGPT直播话术设计正在失效!技术专家紧急预警:3大模型行为偏移信号+话术动态刷新机制(含自动检测脚本)
  • Edge 浏览器实用功能全解析,这些隐藏技巧能大幅提升办公效率
  • 《B4450 [GESP202512 三级] 小杨的智慧购物》
  • AI赋能PPT制作:告别低效设计,开启智能办公新时代
  • 用Python和NumPy手把手实现一个马尔可夫链预测模型(附股市预测代码)
  • 如何用Prompt工程+行为埋点+聚类算法生成动态用户画像,90%团队还在手动打标?
  • Linux内核配置踩坑记:解决‘make menuconfig‘报错[scripts/kconfig/mconf.o] Error 1的完整流程
  • 从Excel趋势线到机器学习:最小二乘法在数据分析中的实战避坑指南
  • 内存架构革新:SRAM与DRAM的物理极限与专业化解决方案
  • 即时通讯软件厂家:为企业定制通信基座
  • 【数据发布】全国637万餐饮服务POI 5月25日更新 非OSM数据
  • 为什么你的ChatGPT头脑风暴总在平庸层打转?揭秘认知科学证实的4类思维阻断信号及实时矫正协议
  • 2026 电商 AI 生图实战指南+四大工具平台评测
  • 【极简监控·进阶篇】AI助力复刻 Glowroot智能截流,打通 SkyWalking-Local告警的任督二脉
  • 从提示词工程、上下文工程到 Harness 工程:AI Agent 工程化演进路径
  • 57.从AOSP源码出发,详解Android/iOS双平台刷机底层核心机制
  • 一分钟搞OSS签名URL
  • 别再死记硬背L1、L2范数了!用Python可视化带你直观理解Lp范数家族
  • ARM处理器调试架构:EDBGRQ与CTI对比与实现
  • 从TRPO到PPO:OpenAI如何用‘Clipping’技巧让强化学习训练更稳定(附PyTorch代码)
  • 开发转兼职DBA(五):从救火到防火——参数、内存、监控、备份
  • ESP32实战指南:NVS非易失性存储数据持久化与结构体存储
  • FModel完全指南:高效提取虚幻引擎游戏资源的实用工具
  • Cortex-R4处理器nCPUHALT信号原理与应用解析
  • 算法与数据结构概述
  • LLM应用安全实战:构建IPI-Scanner防御间接提示注入攻击
  • Redis应用场景深度解析
  • ABAQUS作业XML解析失败:从报错信息到资源调优的实战排查
  • 【力扣100题】62.滑动窗口最大值
  • 读了 GPT-4 分词器源码才明白:为什么 tiktoken 宁可丢掉合并树,也要采用“只读字典”的扁平设计?