1.二叉树的最大深度
给定一个二叉树 root
,返回其最大深度。
示例 1:
- 输入:
root = [3,9,20,null,null,15,7]
- 输出:
3
示例 2:
- 输入:
root = [1,null,2]
- 输出:
2
提示:
- 树中节点的数量在
[0, 104]
区间内。 -100 <= Node.val <= 100
本题可以使用递归法。首先要考虑是的递归三要素:
- 参数和返回值:参数就是树的根节点,返回值是深度int
- 终止条件:节点为空则返回
- 单层递归逻辑:先求左子树深度,再求右子树深度,最后左右子树深度+1就是二叉树的最大深度
代码如下:
/**
* 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 == nullptr) return 0;//返回
int leftdepth = getDepth(node->left);//左子树深度
int rightdepth = getDepth(node->right);//右子树深度
int depth = max(leftdepth, rightdepth) + 1;//加头节点
return depth;
}
int maxDepth(TreeNode* root) {
return getDepth(root);
}
};
本题还可以使用迭代法,层序遍历在之前文章:二叉树层序遍历的模板已经论述,本章只附代码:
/**
* 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) {
queue<TreeNode*> que;
int deep = 0;
if(root != nullptr) que.push(root);
while(!que.empty()) {
int size = que.size();
for(int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
deep++;
}
return deep;
}
};
2.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
示例 1:
- 输入:
root = [3,9,20,null,null,15,7]
- 输出:
2
示例 2:
- 输入:
root = [2,null,3,null,4,null,5,null,6]
- 输出:
5
提示:
- 树中节点数的范围在
[0, 105]
内 -1000 <= Node.val <= 1000
与最大深度类似,但有一点要注意:当左子树为空,右子树非空的时候,最小深度是右子树的深度,反之亦然。
递归三要素:
- 参数和返回值:传入参数root,返回值是最小深度
- 终止条件:遇到空节点返回0,表示当前节点的高度为0
- 单次循环逻辑:左子树为空,右子树非空,返回1+右子树深度;右子树为空,左子树非空,返回1+左子树深度;
/**
* 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 == nullptr) return 0;
int leftdepth = getDepth(node->left);
int rightdepth = getDepth(node->right);
if(node->left == nullptr && node->right != nullptr) return (rightdepth + 1);
if(node->left != nullptr && node->right == nullptr) return (leftdepth + 1);
int result = 1 + min(leftdepth, rightdepth);
return result;
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
3.完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root
,求出该树的节点个数。
示例 1:
- 输入:
root = [1,2,3,4,5,6]
- 输出:
6
示例 2:
- 输入:
root = []
- 输出:
0
示例 3:
- 输入:
root = [1]
- 输出:
1
提示:
- 树中节点的数目范围是
[0, 5 * 10^4]
0 <= Node.val <= 5 * 10^4
- 题目数据保证输入的树是 完全二叉树
进阶:
遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,用
2^树深度 - 1
来统计节点。代码如下:
/**
* 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 countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
- 时间复杂度:O(log n × log n)
- 空间复杂度:O(log n)