前言
这个最大深度就是DFS搜索的概念了,每个路径都搜索,看一下那条路径最长。最长的路径就是最大深度了。
题目
求给定二叉树的最大深度,
深度是指树的根节点到任一叶子节点路径上节点的数量。
最大深度是所有叶子节点的深度的最大值。
(注:叶子节点是指没有子节点的节点。)
数据范围:
0
≤
n
≤
100000
0≤n≤100000
0≤n≤100000,树上每个节点的val满足
∣
v
a
l
∣
≤
100
∣val∣≤100
∣val∣≤100
要求: 空间复杂度
O
(
1
)
O(1)
O(1),时间复杂度
O
(
n
)
O(n)
O(n)
示例1
输入:
{
1
,
2
}
\{1,2\}
{1,2}
返回值:2
示例2
输入:
{
1
,
2
,
3
,
4
,
#
,
#
,
5
}
\{1,2,3,4,\#,\#,5\}
{1,2,3,4,#,#,5}
返回值:3
解决方案一
1.1 思路阐述
我们把找二叉树的最大深度的过程分解一下,分解成找左子树和右子树的过程。
这样一个复杂的问题就不断精简,就成了一样的类似的问题。
先看这个节点有没有定义,定义了则不为空,深度+1,再看这个节点的左子树,再看右子树。
左右子树都和上面一样走一遍。
最后根节点看一下左右子树哪个深度最大,把这个深度加上根节点这一层的深度1,就是我们找到的最大的深度了。
1.2 源码
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
int depth = 0;//根节点深度默认为0,如果根节点有定义则深度+1
int left_depth = 0;//左子树根节点深度默认为0,如果节点有定义则深度+1
int right_depth = 0;//右子树根节点深度默认为0,如果节点有定义则深度+1
if (root)
depth++;
else
return 0;
left_depth += maxDepth(root->left);//左子树的深度
right_depth += maxDepth(root->right);//右子树的深度
//找到左右子树中深度最大的一个并赋值
int tempDepth = left_depth > right_depth ? left_depth : right_depth;
return tempDepth+depth;
}
};
还有更简单的写法
class Solution {
public:
int maxDepth(TreeNode* root) {
//空节点没有深度
if(root == NULL)
return 0;
//返回子树深度+1
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
解决方案二
2.1 思路阐述
既然是统计二叉树的最大深度,除了根据路径到达从根节点到达最远的叶子节点以外,我们还可以分层统计。对于一棵二叉树而言,必然是一层一层的,那一层就是一个深度,有的层可能会很多节点,有的层如根节点或者最远的叶子节点,只有一个节点,但是不管多少个节点,它们都是一层。因此我们可以使用层次遍历,二叉树的层次遍历就是从上到下按层遍历,每层从左到右,我们只要每层统计层数即是深度。
2.2 源码
class Solution {
public:
int maxDepth(TreeNode* root) {
//空节点没有深度
if(root == NULL)
return 0;
//队列维护层次后续节点
queue<TreeNode*> q;
//根入队
q.push(root);
//记录深度
int res = 0;
//层次遍历
while(!q.empty()){
//记录当前层有多少节点
int n = q.size();
//遍历完这一层,再进入下一层
for(int i = 0; i < n; i++){
TreeNode* node = q.front();
q.pop();
//添加下一层的左右节点
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
}
//深度加1
res++;
}
return res;
}
};
总结
树的遍历加上递归的使用,将问题进行拆分,是二叉树的一种精髓了。