📝 题目描述

题目链接二叉树的最大深度

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

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

示例:

示例 1:

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

示例 2:

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

提示:

  • 树中节点的数量在 [0, 10^4] 区间内
  • -100 <= Node.val <= 100

💡 解题思路

方法一:深度优先搜索(递归)

深度优先的思路,如果我们知道了左子树和右子树的最大深度 llrr,那么该二叉树的最大深度即为:

max(l,r)+1max(l,r) + 1

而左子树和右子树的最大深度又可以以同样的方式进行计算。因此我们可以用“深度优先搜索”的方法来计算二叉树的最大深度。具体而言,在计算当前二叉树的最大深度时,可以先递归计算出其左子树和右子树的最大深度,然后在 O(1)O(1) 时间内计算出当前二叉树的最大深度。递归在访问到空节点时退出。

方法二:广度优先搜索(迭代)

广度优先的思路,实际上就是层序遍历的变体。但我们需要对其进行一些修改。

每次循环开始时,广度优先搜索的队列里存放的是“当前层的所有节点”。每次拓展下一层的时候,不同于广度优先搜索的每次只从队列里拿出一个节点,我们需要将队列里的所有节点都拿出来进行拓展,这样能保证每次拓展完的时候队列里存放的是下一层的所有节点,即我们是一层一层地进行拓展,最后我们用一个变量 ans 来维护拓展的次数,该二叉树的最大深度即为 ans

🔧 代码实现

1、深度优先搜索(递归)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int getDepth(TreeNode* node) {
if (!node) return 0;
int leftDepth = 0, rightDepth = 0;
// 计算左右子树的深度
leftDepth = getDepth(node -> left);
rightDepth = getDepth(node -> right);
// 返回深度
return max(leftDepth, rightDepth) + 1;
}
int maxDepth(TreeNode* root) {
return getDepth(root);
}
};

2、广度优先搜索(迭代)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if (!root) return 0;
queue<TreeNode*> qu;
int ans = 0;
qu.push(root);
while(!qu.empty()){
// 获取锁定本层节点数量
int nums = qu.size();
// 增加深度
ans++;
for (int i = 0; i < nums; i++) {
TreeNode* tn = qu.front();
qu.pop();
// 添加下一层节点
if (tn -> left) qu.push(tn -> left);
if (tn -> right) qu.push(tn -> right);
}
}
return ans;
}
};

📊 复杂度分析

1、深度优先搜索(递归)

  • 时间复杂度O(n)O(n),其中 nn 为二叉树节点的个数。每个节点在递归中只被遍历一次。
  • 空间复杂度O(height)O(height),其中 heightheight 表示二叉树的高度。递归函数需要栈空间,而栈空间取决于递归的深度,因此空间复杂度等价于二叉树的高度。

2、广度优先搜索(迭代)

  • 时间复杂度O(n)O(n),其中 n 为二叉树的节点个数。与方法一同样的分析,每个节点只会被访问一次。
  • 空间复杂度O(n)O(n),此方法空间的消耗取决于队列存储的元素数量,其在最坏情况下会达到 O(n)O(n)

🎯 总结

  • 核心思想:掌握层序遍历的思路(锁面板)。