Leetcode 104. 二叉树的最大深度
题目链接 104 二叉树的最大深度
昨天已经用层序遍历模板(广度优先遍历)已经做过了,我们现在用递归法来做一下这个题目,在做之前,需要了解两个点:
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。
接着还有我们二叉树递归的三个步骤:
- 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
- 确定终止条件:如果为空节点的话,就返回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 == NULL){
return 0;
}
int leftdepth = getdepth(node->left);//左
int rightdepth = getdepth(node->right);//右
int depth = 1+max(leftdepth,rightdepth);//中
return depth;
}
int maxDepth(TreeNode* root) {//并不是真正意义上的根
return getdepth(root);//
}
};
Leetcode 111 二叉树的最小深度
题目链接 111 二叉树的最小深度
本题昨天也写过了,今天用递归法写一下,这里有一个陷阱,就是题目定义了 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。如果左右节点有NULL就不能算到深度上面,只能算子节点不为空的节点,下面上代码:
class Solution {
public:
int getDepth(TreeNode* node) {
if (node == NULL) return 0;
int leftDepth = getDepth(node->left); // 左
int rightDepth = getDepth(node->right); // 右
// 中
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL) {
return 1 + rightDepth;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL) {
return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
return result;
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
Leetcode 222 完全二叉树的节点个数
题目链接 222 完全二叉树的节点个数
思路:先求它的左子树的节点数量,再求右子树的节点数量,最后取总和再加一
这里是没有运用完全二叉树的特性,就按照普通二叉树来做。
代码:
class Solution {
private:
int getNodesNum(TreeNode* cur) {
if (cur == NULL) return 0;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
public:
int countNodes(TreeNode* root) {
return getNodesNum(root);
}
};
如果仔细观察完全二叉树的特性:
情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
情况一:可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为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 countNodes(TreeNode* root) {
if(root == NULL){
return 0;
}
TreeNode* left = root->left;//定义指针来判断深度是否相等
TreeNode* right = root->right;
int leftDepth = 0,rightDepth = 0;
while(left){
left = left->left;
leftDepth++;
}
while(right){
right = right->right;
rightDepth++;
}
if(leftDepth == rightDepth){
return (2<<leftDepth)-1;//位运算,2<<1相当于2^2
}
int leftTreeNum = countNodes(root->left);
int rightTreeNum = countNodes(root->right);
int result = leftTreeNum + rightTreeNum + 1;
return result;
}
};
end