【力扣100题】27. 二叉树的最大深度

一、题目描述

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

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


二、解题思路总览

方法 核心思想 时间复杂度 空间复杂度
递归(DFS) 后序遍历,左右子树深度+1 O(n) O(h),h为树高
迭代(BFS) 层序遍历,统计层数 O(n) O(n),队列最大层宽度

选择建议

  • 递归:代码简洁,面试首选
  • 迭代:直观展示层数,不需要递归思维

三、完整代码

方法一:递归(DFS 后序遍历)

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        // 递归终止条件:空节点深度为0
        if (!root) return 0;

        // 递归计算左子树深度
        int leftDepth = maxDepth(root->left);

        // 递归计算右子树深度
        int rightDepth = maxDepth(root->right);

        // 返回较大深度+1(加上当前根节点)
        return max(leftDepth, rightDepth) + 1;
    }
};

方法二:迭代(BFS 层序遍历)

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root) return 0;              // 空树深度为0

        queue<TreeNode*> q;               // 层序遍历队列
        q.push(root);                     // 根节点入队
        int depth = 0;                     // 深度计数器

        while (!q.empty()) {              // 队列不为空时循环
            int size = q.size();          // 当前层节点数

            // 遍历当前层所有节点
            for (int i = 0; i < size; i++) {
                TreeNode* node = q.front();
                q.pop();

                // 把下一层子节点入队
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }

            depth++;                       // 处理完一层,深度+1
        }

        return depth;
    }
};

四、算法流程图(ASCII)

递归版流程

复制代码
以 root = [3, 9, 20, null, null, 15, 7] 为例:

        3                    深度 = max(左深度, 右深度) + 1
       / \
      9   20                max(1, 2) + 1 = 3
          / \
         15  7

递归展开过程:

    maxDepth(3)
        │
        ├── maxDepth(9) ──→ return 1 (叶子节点)
        │
        └── maxDepth(20)
                │
                ├── maxDepth(15) ──→ return 1
                └── maxDepth(7)  ──→ return 1

    计算:max(1, max(1,1)+1)+1 = max(1, 2)+1 = 3

迭代版流程

复制代码
层序遍历,统计层数

    第1层:队列[3]           depth=1
    第2层:队列[9,20]        depth=2
    第3层:队列[15,7]        depth=3
    第4层:队列[]            depth=3,结束

    最大深度 = 3

五、逐行解析

递归版逐行解析

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        // ─────────────────────────────────────────
        // 第1步:递归终止条件
        // 空节点没有子树,深度为0
        // 这是递归的出口
        // ─────────────────────────────────────────
        if (!root) return 0;

        // ─────────────────────────────────────────
        // 第2步:递归计算左子树深度
        // 后序遍历:先处理左子树
        // 递归调用会一直深入到叶子节点
        // ─────────────────────────────────────────
        int leftDepth = maxDepth(root->left);

        // ─────────────────────────────────────────
        // 第3步:递归计算右子树深度
        // 后序遍历:再处理右子树
        // ─────────────────────────────────────────
        int rightDepth = maxDepth(root->right);

        // ─────────────────────────────────────────
        // 第4步:返回较大深度 + 1
        // max(leftDepth, rightDepth) 取较大的子树
        // +1 是因为要加上当前根节点这一层
        // ─────────────────────────────────────────
        return max(leftDepth, rightDepth) + 1;
    }
};

迭代版逐行解析

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root) return 0;          // 空树直接返回0

        queue<TreeNode*> q;           // BFS用队列
        q.push(root);                 // 根节点入队
        int depth = 0;                 // 初始深度0

        // ─────────────────────────────────────────
        // 外层循环:一层层处理
        // 队列为空说明所有节点都处理完了
        // ─────────────────────────────────────────
        while (!q.empty()) {
            int size = q.size();      // 当前层的节点数量

            // ─────────────────────────────────────────
            // 内层循环:处理当前层的所有节点
            // 把它们的子节点加入队列(下一层)
            // ─────────────────────────────────────────
            for (int i = 0; i < size; i++) {
                TreeNode* node = q.front();
                q.pop();

                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }

            // ─────────────────────────────────────────
            // 当前层处理完毕,深度+1
            // ─────────────────────────────────────────
            depth++;
        }

        return depth;
    }
};

六、复杂度分析

时间复杂度

方法 分析 复杂度
递归 每个节点访问一次 O(n)
迭代 每个节点访问一次 O(n)

推导:n 个节点,每个节点只被访问一次。

空间复杂度

方法 分析 复杂度
递归 函数调用栈,最大深度为树高h O(h)
迭代 队列,最大宽度为最宽层的节点数 O(n)

递归推导

  • 最坏情况(链表形状):h = n,复杂度 O(n)
  • 平衡树情况:h = log n,复杂度 O(log n)

迭代推导

  • 最宽层可能有 n/2 个节点,复杂度 O(n)

七、面试追问 FAQ

问题 回答
递归的思路是什么? 后序遍历,左右子树深度取较大者,再+1
如何理解 +1 当前根节点算一层,所以左右子树深度取max后要+1
为什么递归比迭代空间复杂度低? 递归栈深度是树高h,迭代队列宽度最大是n/2
如何求最小深度? 改成 min(leftDepth, rightDepth),但要注意只有一边的特殊情况
最大深度和高度有什么区别? 最大深度从根数到叶子(自顶向下),高度从叶子数到根(自底向上)

八、相关题目

题目 难度 关键点
104. 二叉树的最大深度 简单 本题
111. 二叉树的最小深度 简单 min + 特殊判断
110. 平衡二叉树 简单 最大深度 + 高度差判断
104. 二叉树的最大深度(迭代) 简单 BFS层序遍历
剑指 Offer 55-I. 二叉树的深度 简单 同本题

九、总结

对比项 递归 迭代
代码量 少(核心5行) 较多(队列操作)
时间复杂度 O(n) O(n)
空间复杂度 O(h) O(n)
适用场景 面试首选 需要直观层数时

核心公式

复制代码
最大深度 = max(左子树深度, 右子树深度) + 1

相关推荐
bzmK1DTbd1 小时前
K-Means聚类算法:无监督学习实战
算法·kmeans·聚类
_深海凉_1 小时前
LeetCode热题100-删除链表的倒数第 N 个结点
算法·leetcode·链表
小雅痞1 小时前
[Java][Leetcode middle] 73. 矩阵置零
java·leetcode·矩阵
Yzzz-F1 小时前
Problem - 2043E - Codeforces EDU173
算法
栈溢出了1 小时前
GraphSAGE 学习笔记
深度学习·神经网络·算法·机器学习
AI科技星2 小时前
全域数学版木牛流马(融合仿生兽+古制复原终版优化方案)【乖乖数学】
人工智能·算法·数学建模·数据挖掘·量子计算
richard_yuu2 小时前
数据结构精讲:图的最短路径与关键路径
数据结构·算法
智者知已应修善业2 小时前
【51单片机一个按键切合初始流水灯按一下对半闪烁按一下显示时间】2023-10-16
c++·经验分享·笔记·算法·51单片机
晚风叙码2 小时前
堆排序建堆策略对比:向上调整与向下调整的时间复杂度分析
算法