代码随想录 最大深度

1.二叉树的最大深度

理论基础:

        深度:节点到根节点的距离

        高度:节点到叶子节点的距离

        不论是高度还是深度,都是从1开始,节点为空时,为0;

class Solution {
public:
    //解题思路:根节点的最大深度=最大高度,故而可采用后序遍历,依次从叶子节点往上遍历。
    //每遍历一层,便将高度加1
    //后序遍历 左右中 可采用递归方法
    //迭代法:可以采用层序遍历,每次加一层的元素加入队列,放出时若不为空则改变深度
    
    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);
    }
};

2.最小深度

注意:一定要有叶节点;其次,求最小深度,只需要求左右节点的最小深度即可,这样一层层迭代下去,求的即为根节点到叶节点的最小深度。

https://leetcode.cn/problems/minimum-depth-of-binary-tree/submissions/

class Solution {
public:
    //题目是计算根节点到叶节点的最小深度,也就是一定要有叶节点;若根节点的左右节点为空,是没有叶结点的
    //解题思路:采用后序遍历,计算其高度,然后返回也节点的最小深度;但要注意根节点的左右叶子节点为空的情况  
    int getMinDepth(TreeNode* cur){
        if(cur == nullptr) return 0;    //空节点的高度为0

        int leftDepth = getMinDepth(cur->left);     //左
        int rightDepth = getMinDepth(cur->right);   //右

        if(cur->left == nullptr && cur->right != nullptr) return 1+rightDepth;
        if(cur->left != nullptr && cur->right == nullptr) return 1+leftDepth;

        return 1+min(leftDepth,rightDepth);
    }
    
    int minDepth(TreeNode* root) {
        
        return getMinDepth(root);
    }
};

三、完全二叉树的节点数量

https://leetcode.cn/problems/count-complete-tree-nodes/submissions/

class Solution {
public:
    //迭代法:采用层序遍历,队列没加入一个,计数器加1
    //递归法:遍历后序遍历,遍历左右子树的节点数,再求和;也可前中序遍历
            
    //后序递归
    int getNodes(TreeNode* cur){
        // //普通二叉树求节点个数
        // if(cur == nullptr) return 0;

        // int left = getNodes(cur->left);     //左
        // int right = getNodes(cur->right);   //右

        // int result = left + right +1;       //中
        // return result;

        //应用完全二叉树的性质:在完全二叉树中,除了最底层节点可能没填满外,
        //其余每层节点数都达到最大值;
        //并且最下面一层的节点都集中在该层最左边的若干位置。
        //若最底层为第 h 层,则该层包含 1~ 2^(h-1)  个节点。

        //所以,只要能够确定子树是否为满二叉树,即可按照公式确定其数量
        //相当于在普通二叉树求节点数中,加上一个判断,确定其子树是否满二叉树

        //情况一为满二叉树,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
        //情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

        //在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。
        if(cur == nullptr) return 0;    //终止条件
        //终止条件2 遇到满二叉树,直接按照公式计算这棵树的节点数,减少遍历的次数
        //判断当前节点的左右子树是否为满二叉树
        TreeNode* left =cur->left;
        TreeNode* right = cur->right;
        int ldepth = 0;
        int rdepth = 0;
        while(left){
            left = left->left;
            ldepth++;
        }
        while(right){
            right = right->right;
            rdepth++;
        }
        //是满二叉树进行公式计算节点
        if(ldepth == rdepth) return (2<<ldepth)-1; // 注意(2<<1) 相当于2^2,所以lDepth=0,为2-1=1

        //若不是满二叉树 依然要进入递归
        // int left = getNodes(cur->left);     //左
        // int right = getNodes(cur->right);   //右
        int result = getNodes(cur->left) +  getNodes(cur->right) +1;       //中
        return result;
    }


    int countNodes(TreeNode* root) {
        return getNodes(root) ;   
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值