代码随想录算法训练营day 16|第六章 二叉树part03

104.二叉树的最大深度 (优先掌握递归)

什么是深度,什么是高度,如何求深度,如何求高度,这里有关系到二叉树的遍历方式。大家 要先看视频讲解,就知道以上我说的内容了,很多录友刷过这道题,但理解的还不够。

题目链接/文章讲解/视频讲解: 代码随想录

二叉树的深度:当前节点到根节点的长度。——根节点深度为0,故而前序遍历。
二叉树的高度:当前节点到叶子节点的长度,取最长。——叶子节点高度为0,故而后序遍历。

但是,对于一棵二叉树来讲,根节点的最大高度就是这个二叉树的最大深度,所以可以通过后序遍历来求最大深度——

int maxDepth(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;
    }

文章里面也介绍了前序遍历来求最大深度。递归函数首先确定每次的参数必须有的depth,否则没办法确定当前节点的子结点的深度,因为最大深度只能有一个数值,每次递归函数需要试图更新result,所以需要将result设置为类的变量,这样每次递归函数更新的都是同一个result。处理完根节点,判断是否存在左子树和右子树,不存在就直接返回,否则要继续调用递归函数来试图更新result——

class solution {
public:
    int result;
    void getdepth(TreeNode* node, int depth) {
        result = depth > result ? depth : result; // 中
        if (node->left == NULL && node->right == NULL) return ;
        if (node->left) { // 左
            getdepth(node->left, depth + 1);
        }
        if (node->right) { // 右
            getdepth(node->right, depth + 1);
        }
        return ;
    }
    int maxDepth(TreeNode* root) {
        result = 0;
        if (root == 0) return result;
        getdepth(root, 1);
        return result;
    }
};

最后,使用迭代法求最大深度其实就是用层序遍历法来求。

111.二叉树的最小深度 (优先掌握递归)

先看视频讲解,和最大深度 看似差不多,其实 差距还挺大,有坑。

题目链接/文章讲解/视频讲解:代码随想录

使用后序遍历。不像求最大深度那样简单,因为要排除非叶子节点的子结点为NULL的干扰,如果不处理,就会导致一旦子结点出现NULL,就会直接认定该节点的最小深度是1,但这样是不符合深度的定义的,应该是到叶子节点的长度,而叶子节点的两个子节点都要是NULL才行,这样只保证了其中一个子节点是NULL,于是要判断如果只是一个子节点为NULL,那递归调用的时候,就只用返回所求不空的子节点的最小高度加一就行——

int minDepth(TreeNode* root) {
        if (root == NULL) return 0;
        if (root->left == NULL && root->right != NULL) {
            return 1 + minDepth(root->right);
        }
        if (root->left != NULL && root->right == NULL) {
            return 1 + minDepth(root->left);
        }
        return 1 + min(minDepth(root->left), minDepth(root->right));
    }

使用前序遍历。大体来说和求最大深度差不多,要注意两点,第一点是要先设置result值为INT_MAX,否则可能存在更新不了result的情况;第二点是要事先判断root是否为空,否则会直接返回INT_MAX为最小深度——

class Solution {
public:
    int result=INT_MAX;
    // bool find=false;
    void getDepth(TreeNode* node,int depth){
        if(!node) return ;
        if((!node->left&&!node->right)) {
            result=result<depth?result:depth;
        }
        
        if(node->left) getDepth(node->left,depth+1);
        if(node->right) getDepth(node->right,depth+1);
    }
    int minDepth(TreeNode* root) {
        if(root==NULL) return 0;
        getDepth(root,1);
        return result;
    }
};

迭代法也可以解决,就是使用层序遍历。

222.完全二叉树的节点个数(优先掌握递归)

需要了解,普通二叉树 怎么求,完全二叉树又怎么求

题目链接/文章讲解/视频讲解:代码随想录

普通二叉树——

递归方法——

int countNodes(TreeNode* root) {
        if (root == NULL) return 0;
        return 1 + countNodes(root->left) + countNodes(root->right);
    }

迭代方法——

使用层序遍历即可。

完全二叉树——

首先由于是完全二叉树,所以必然存在子树是满二叉树,而计算满二叉树的节点数量是很容易的,直接调用公式即可(2<<深度-1),所以一旦知道是满二叉树就意味着剩下的节点不用继续遍历了。这时候可以在每次递归调用之前,先行判断是否满二叉树(判断方法:对于完全二叉树来讲,只要满足最左叶子节点的深度和最右叶子节点的深度相等,即意味着满二叉树)——

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;
    }
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值