#打卡记录
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
104.二叉树的最大深度
后序遍历符合高度的计算的过程,即从叶子节点开始一个个往上数高度的过程。后续遍历是左右中的过程,中即执行操作的部分,后续会一路遍历到叶子节点,再逐层返回当前深度。
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);
}
};
前序遍历的过程符合深度的计算的过程,即从根节点开始一个个往下数深度的过程。前序遍历是中左右的过程,在往下继续遍历前进行计算操作,每下一层计算当前最大深度,一直到叶子节点。
迭代法用层序遍历更好理解,这里为了练习用栈模拟递归的过程,写成以下形式。
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == nullptr) return 0;
stack<pair<TreeNode*, int>> st;
st.push({root, 1});
int maxdepth = 0;
while(!st.empty()){
TreeNode* node = st.top().first;
int depth = st.top().second;
st.pop();
maxdepth = max(maxdepth, depth);
if(node->left) st.push({node->left, depth+1});
if(node->right) st.push({node->right, depth+1});
}
return maxdepth;
}
};
111.二叉树的最小深度
这题注意的是判定条件,我们要寻找的是到叶子节点的最小深度,所以只在到也叶子节点的时候进行处理计算。
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == nullptr) return 0;
stack<pair<TreeNode*, int>> st;
st.push({root, 1});
int mindepth = INT_MAX;
while(!st.empty()){
TreeNode* node = st.top().first;
int depth = st.top().second;
st.pop();
if(!node->left && !node->right) mindepth = min(mindepth, depth);//到叶子节点计算最小深度
if(node->left) st.push({node->left, depth+1});
if(node->right) st.push({node->right, depth+1});
}
return mindepth;
}
};
222.完全二叉树的节点个数
这题的重点在于合理利用树的性质,能降低时间复杂度。
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
判断其子树是不是满二叉树,如果是则利用公式计算这个子树(满二叉树)的节点数量,如果不是则继续递归。这样就可以省去一些节点的遍历。
class Solution {
public:
int countNodes(TreeNode* root) {
if(root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftnum = 0;
int rightnum = 0;
int ans = 0;
while(left){
left = left->left;
leftnum++;
}
while(right){
right = right->right;
rightnum++;
}
if(leftnum == rightnum) return (2 << leftnum) -1;
ans = countNodes(root->left) + countNodes(root->right) + 1;
return ans;
}
};