算法学习打卡day15 |104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

104.二叉树的最大深度

力扣题目链接
题目描述:
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:
输入:root = [1,null,2]
输出:2

思路:

  • 递归法:采用后序遍历,分别求左子树和右子树的深度,取最大值即可。递归三部曲如下:
    • 确定参数和返回值:参数是根节点,返回值为深度int即可
    • 函数退出条件:当节点为空,return 0;
    • 单步处理逻辑:分别递归左节点和右节点,然后取它们返回值的最大值 + 1。
      代码实现:
int maxDepth(TreeNode* root) {
        if (root == nullptr)    return 0;
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return (left > right ? left : right) + 1;
    }
  • 迭代法:采用层次遍历,遍历到每层的时候depth+1,最终得到层数
int maxDepth(TreeNode* root) {
        if(root == nullptr) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int depth = 0;
        int size = 0;
        while(!que.empty()) {
            size = que.size();
            depth++;
            for(int i = 0 ; i < size; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur->left)   que.push(cur->left);
                if (cur->right)  que.push(cur->right);
            }
        }
        return depth;
    }

111.二叉树的最小深度

力扣题目链接
题目描述:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

思路:

  • 递归法: 这道题和求最大深度类似,但是注意这里有个误区就是,它不是取左右子树的高度最小值,如果遇到左子树空右子树不空这种情况返回的是0,而此时右子树递归返回的是非0,两者取最小值最终返回的是0,这肯定不对。所以需要修改,在左子树为空右子树非空时,用右子树最小深度,而反之亦然,都为空(都为空时,递归两个子树得到的结果都是0)或者都不为空的时候取两个子树最小深度即可,递归三部曲如下
    • 函数参数和返回值:参数为根节点、返回值为最小深度
    • 退出条件:当节点为空的时候return 0;
    • 单步处理逻辑:左子树为空右子树非空,return left_depth + 1;右子树为空,左子树非空,return right_depth + 1; 都为空或者都不为空return min(left_depth, right_depth) + 1;

代码实现:

int minDepth(TreeNode* root) {
        if (root == nullptr)    return 0;
        int left_depth =  minDepth(root->left);
        int right_depth = minDepth(root->right);
        if (root->left && !root->right) {
            return left_depth + 1;
        } else if (!root->left && root->right) {
            return right_depth + 1;
        }
        return min(left_depth,  right_depth) + 1;       
    }
  • 迭代法:采用层次遍历,遍历每层时遇到叶子节点退出即可(左右子树都为空的时候)

代码实现:

int minDepth(TreeNode* root) {
        if (root == nullptr)    return 0;
        queue<TreeNode*> que;
        que.push(root);
        int size = 0, depth = 0;
        while(!que.empty()) {
            size = que.size();
            depth++;
            for (int i = 0; i < size; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                if (!cur->left && !cur->right) {
                    return depth;
                }
                if (cur->left)  que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }
        }    
        return depth;  
    }

222.完全二叉树的节点个数

力扣题目链接
题目描述:
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

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

  • 方法一:按照普通二叉树来做的话,递归法就是分别求左右子树的节点数量,然后求和+1即可。而迭代法就是层次遍历(前中后序后可以),然后求节点个数。

代码实现:

//递归法
int countNodes(TreeNode* root) {
        if (root == nullptr)    return 0;
        int left_count = countNodes(root->left);
        int right_count = countNodes(root->right);
        return left_count + right_count + 1;
    }
//迭代法
int countNodes(TreeNode* root) {
        if (root == nullptr)    return 0;
        queue<TreeNode*> que;
        que.push(root);
        int size = 0, sum = 0;
        while(!que.empty()) {
            size = que.size();
            for (int i = 0; i < size; ++i) {
                TreeNode* cur = que.front();
                que.pop();
                sum++;
                if (cur->left)  que.push(cur->left);
                if (cur->right) que.push(cur->right);
            }        
        }
        return sum;
    }
  • 方法二:利用完全二叉树的性质做题,完全二叉树的子树也是完全二叉树,然后我们去判断它是不是满二叉树,如果是满二叉树直接利用公式计算,否则就递归判断子树。
  • 递归三部曲:
    • 确定函数参数和返回值:函数参数为根节点和,返回值为int类型
    • 退出条件:根节点为空时,return 0;
    • 单步逻辑:先判断是不是满二叉树,如果是满二叉树直接求节点数就行,不是满二叉树交给递归。
    • 如何判断满二叉树?
      • 由于题目已经给出输入的一定是完全二叉树,那么我们沿着左子树一直往左找,直到left指针为空,这个节点一定是叶子节点,而右子树一样的道理,然后求出左子树和右子树的深度,如果深度相等就是满二叉树。

代码实现:

int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;
        int left_depth = 0, right_depth = 0;
        TreeNode* cur = root->left;
        while(cur) {
            left_depth++;
            cur = cur->left; 
        }
        cur = root->right;
        while(cur) {
            right_depth++;
            cur = cur->right;
        }
        if (left_depth == right_depth) {
            return (2 << left_depth) - 1; //这里是 2 *(2^h - 1)+ 1,化简后为 2^(h+1) -1,换为位运算就是(2<< h) - 1
        } else{
            return countNodes(root->left) + countNodes(root->right) + 1;
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值