104. 二叉树的最大深度
视频讲解
主要思路:
(1)因为要求的最大深度其实就是高度,所以采用后序遍历,(一般来说,求高度都用后序遍历,求深度都用前序遍历)
(2)递归三步:
1. 参数:节点;返回值:该节点深度
2. 结束条件:节点为空
3. 递归逻辑:后序遍历
”左右“:都是递归调用
“中”:是处理逻辑
易错点
(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 maxDepth(TreeNode* root) {
if(root == NULL) return 0;
int leftHight = maxDepth(root -> left);
int rightHight = maxDepth(root -> right);
int ans = max(leftHight, rightHight) + 1;
return ans;
}
};
111. 二叉树的最小深度
视频讲解
主要思路:
(1)首先看清题目要求,求的是根节点到最小叶子结点的距离
(2)依然采用后序遍历,通过将孩子情况返回给父节点,因为高度从1开始,所以父节点+1
易错点:
(1)递归结束为什么返回0:
因为此时已遍历到叶子节点,高度是1,再往下的NULL节点高度是0
(2)“中”的处理逻辑:
不能贸然取两个子树中高度较小的一个,因为如果有一个子树为空,那么所谓"最小值"并没有从叶子节点开始计算
代码实现:
/**
* 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 minDepth(TreeNode* root) {
if(root == NULL) return 0;
int leftHeight = minDepth(root -> left);
int rightHeight = minDepth(root -> right);
int minHeight;
if(root -> left == NULL && root -> right != NULL) minHeight = rightHeight + 1;
else if(root -> left != NULL && root -> right == NULL) minHeight = leftHeight + 1;
else minHeight = min(leftHeight, rightHeight) + 1;
return minHeight;
}
};
222. 完全二叉树的节点个数
视频讲解
手撕+模拟
主要思路:
通过后序遍历一棵一棵找到满二叉树后加上去
易错点:
(1)递归结束条件:
1. 遍历到叶子结点
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 == NULL) return 0;
TreeNode* leftNode = root -> left;
TreeNode* rightNode = root -> right;
int leftDepth = 0;
int rightDepth = 0;
while(leftNode) {
leftNode = leftNode -> left;
leftDepth++;
}
while(rightNode) {
rightNode = rightNode -> right;
rightDepth++;
}
//求出当前满二叉树的节点总数
if(leftDepth == rightDepth) return (2 << leftDepth) - 1;
//后序遍历里"左右"递归调用
int leftSubtree = countNodes(root -> left);
int rightSubtree = countNodes(root -> right);
//后序遍历里"中"处理,左右满二叉树节点相加再加当前根节点
return leftSubtree + rightSubtree + 1;
}
};
第一次写错误
(1)对于while里是leftNode还是leftNode -> left其实也关系到leftDepth为什么赋值是0,如果while里是leftNode -> left,则有可能leftNode已经是空节点了,那就操作空指针了,所以while里是leftNode,对应leftDepth也应该赋为0,以叶子结点为例,能进入循环,leftDepth变为1后退出循环,正好是层数