链接:104. 二叉树的最大深度 - 力扣(LeetCode)
题目
给定一个二叉树 root
,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:3
思路
一、递归
对左右子树进行递归,当到达叶节点返回1,空节点返回0,然后依次给最大深度的节点深度加一。
代码实现
/**
* 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) {
//空指针则返回0
if(root==nullptr){
return 0;
}
//叶节点,返回1
if(root->left==nullptr&&root->right==nullptr){
return 1;
}
//左右子树递归
int maxleft=maxDepth(root->left);
int maxright=maxDepth(root->right);
//比较使最深的子树返回深度加一
if(maxleft>=maxright){
return maxleft+1;
}
else{
return maxright+1;
}
}
};
简化写法:
class Solution {
public:
int maxDepth(TreeNode* root) {
return root==nullptr ? 0 : max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
二、广度优先搜索BFS
也叫层序遍历
利用队列实现,将每层节点入队,出队时依次将每个结点的左右非空节点入队,本层节点全部出队后进入下一层的遍历,所以层数加一,层数就是树的深度。待所有节点都遍历后返回深度。
代码实现:
/**
* 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==nullptr){
return 0;
}
//定义一个队列
queue<TreeNode*> q;
//根节点入队
q.push(root);
//统计树的深度
int count=0;
while(!q.empty()){
int n=q.size();//每一层的节点个数
while(n--){
//将每层节点的左右孩子入队
TreeNode* cur=q.front();
q.pop();
if(cur->left){
q.push(cur->left);
}
if(cur->right){
q.push(cur->right);
}
}
//层数加一,层数即为深度
count++;
}
return count;
}
};
结果:
三、深度优先搜索DFS
深度优先搜索就是从根节点开始沿着一条路径往下遍历,直到遇到空节点不能继续遍历,然后返回到上一个节点从另一条路径继续向下遍历,直到所有节点都被访问为止。
这里用栈实现对节点和所在层数的存储,于是用c++提供的模板类pair存储Treenode类型和int类型,使用时分别用first和second访问第一个和第二个参数,只要栈不为空就继续遍历,遍历时先存储栈顶,再出栈,每次比较当前层数和目前的最大深度,取最大值更新后,再访问左右子节点,记得将层数加一,全部遍历完返回最大深度即可。
代码实现:
/**
* 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==nullptr){
return 0;
}
//定义栈,双数据类型分别存储树节点和所在层数
stack<pair<TreeNode*,int>> st;
//根节点入栈,层数为1
st.push({root,1});
int maxcount=0;
while(!st.empty()){
//由于pair有两个数据类型,所以用auto类型
auto cur=st.top();
st.pop();
//取最大值,注意cur为pair模板类,调用second即为第二个参数int类型也就是层数
maxcount=max(maxcount,cur.second);
//左右遍历,入栈,cur.first即为节点类型
if(cur.first->right){
st.push({cur.first->right,cur.second+1});
}
if(cur.first->left){
st.push({cur.first->left,cur.second+1});
}
}
return maxcount;
}
};
注意:
pair
是C++标准库中的一个模板类,用于存储两个不同类型的值,并将它们作为一个单元进行管理。
pair
的定义如下:
template <class T1, class T2>
struct pair {
T1 first;
T2 second;
};
其中T1
和T2
可以是任意类型。
pair
的用法主要包括以下几个方面:
1、创建pair
对象:
pair<int, double> p1(10, 3.14); // 使用值初始化
pair<int, double> p2 = make_pair(5, 2.5); // 使用make_pair函数创建
2、访问pair
对象的成员:
int x = p1.first; // 获取第一个值,即 10
double y = p1.second; // 获取第二个值,即 3.14
3、修改pair
对象的成员:
p1.first = 20; // 修改第一个值为 20
p1.second = 6.28; // 修改第二个值为 6.28
4、比较pair
对象的大小:
pair<int, double> p1(10, 3.14);
pair<int, double> p2(20, 6.28);
bool result = (p1 < p2); // 比较p1和p2的大小,结果为true
auto
是C++11中引入的关键字,用于自动推导变量的类型。使用auto
可以让编译器根据初始化表达式的类型来推导变量的类型,从而简化代码并减少类型冗余。
下面是使用auto
的一些优点和使用场景:
-
减少冗余:使用
auto
可以避免手动指定变量类型,减少代码中的类型冗余,提高代码的可读性。 -
简化复杂类型:当变量的类型很长或复杂时,使用
auto
可以避免手动写出完整的类型名称,减少代码的复杂性。 -
泛型编程:
auto
可以与模板一起使用,用于处理不同类型的对象,使代码更加灵活和通用。 -
函数返回类型推导:在函数定义中,可以使用
auto
来自动推导返回类型,特别适用于复杂的返回类型或涉及模板的情况。 -
迭代器和范围遍历:使用
auto
可以自动推导迭代器和范围遍历所需的类型,使代码更简洁、易读。 -
Lambda表达式:在使用Lambda表达式时,使用
auto
可以方便地声明和推导Lambda函数的类型。
虽然auto
有这些好处,但也需注意:
-
可读性和维护性:过度使用
auto
可能使代码难以理解,尤其是在没有清晰初始化表达式的情况下。适当使用auto
可以提高代码的可读性,但需更好地命名和注释变量。 -
隐藏信息:类型推导可能隐藏变量的实际类型,使代码的含义难以理解和推断。在某些情况下,显式指定类型可能更好地表达代码的意图。