①二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回它的最大深度 3 。
1.每次递归返回左子树或右子树的更大深度,依此计数,得出最大深度:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == NULL) //如果根节点为空,返回深度为0
return 0;
return 1 + max(maxDepth(root->left), maxDepth(root->right)); //每次递归深度+1
}
};
2.采用层序遍历,在遍历到每一层时计数器加1,通过队列保存节点得以实现层序遍历:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == NULL)
return 0;
int cnt = 0; //计数器cnt
queue<TreeNode*> q; //队列q保存节点的信息
q.push(root);
while (!q.empty()) //根节点不为空,继续迭代
{
++cnt; //遍历每一层二叉树计数器+1
int n = q.size();
for (int i = 0;i < n;++i) //保存下一层所有节点的信息
{
TreeNode* node = q.front(); //循环,node为上一层的每个节点
q.pop();
if (node->left) q.push(node->left); //如果当前节点的左节点或右节点不为空,则存入队列,遍历下一层时使用
if (node->right) q.push(node->right);
}
}
return cnt; //遍历完成返回计数器,得到最大深度
}
};
②二叉树的层次遍历Ⅱ
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回其自底向上的层次遍历为:
[ [15,7], [9,20], [3] ]
1.非递归层次遍历:跟计算最大深度雷同,只不过不用计算深度,可以借助其思想,在遍历每一层时,将每一层的元素存入容器,再在遍历完当前层时,将保存当前层元素的容器存入目标容器中:
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
if (root == NULL)
return vector<vector<int>>(0); //根节点为空返回空目标容器
vector<vector<int>> vec; //创建目标容器
queue<TreeNode*> q; //保存节点信息的队列
q.push(root);
while (!q.empty()) //逐层遍历
{
vector<int> vec1; //保存当前层元素的容器
int n = q.size();
for (int i = 0;i < n;++i) //访问当前层所有节点
{
TreeNode* node = q.front();
q.pop();
vec1.push_back(node->val); //将当前层所有节点信息存入容器
if (node->left)
{
q.push(node->left); //保存下一层节点的信息
}
if (node->right)
{
q.push(node->right);
}
}
vec.insert(vec.begin(),vec1); //将保存当前层节点信息的容器插入到目标容器首位(实现由底向上)
}
return vec; //返回目标容器
}
};
2.递归层次遍历:编写一个层次遍历函数进行递归,该函数的参数为一个二维数组和一个变量level(核心),当level递归到上一层的个数,我们新建一个空层,继续往里面加数字:
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> vec;
if (root == NULL) return vec;
level_order(root, 0, vec); //递归层序遍历
return vector<vector<int>> (vec.rbegin(), vec.rend()); //返回逆序,得到自底向上的遍历结果
}
void level_order(TreeNode* root, int level, vector<vector<int>> &vec)
{
if (root == NULL) return;
// 将当前的节点信息放入vec结果中
// 首先判断要不要为当前节点开辟一个新的vector<int>
if (vec.size() == level) vec.push_back({});
vec[level].push_back(root->val);
if (root->left) level_order(root->left, level + 1, vec); //递归遍历左右节点
if (root->right) level_order(root->right, level + 1, vec);
}
};