当前位置: 首页 > news >正文

代码随想录刷题day42|(二叉树篇)二叉树的最小深度(递归)+完全二叉树结点个数

目录

一、二叉树理论知识

二、最小深度思路

三、完全二叉树求节点思路

四、相关算法题目

五、总结


一、二叉树理论知识

详见:代码随想录刷题day34|(二叉树篇)二叉树的递归遍历-CSDN博客

二、最小深度思路

2.1 递归法

同最大深度,不同点在于,求最小深度时,要单独处理,左子树不为空或者右子树不为空的情况,否则容易出错;(五总结里的错误

2.2 迭代法

详见:代码随想录刷题day38|(二叉树篇)二叉树的层序遍历(429、515、116、117、104、111)-CSDN博客

三、完全二叉树求节点思路

基于完全二叉树的特性:借助满二叉树

满二叉树是一种特殊的二叉树,其中每一层的节点数都达到了可能的最大值。这意味着在满二叉树中,除了叶子节点外,每个节点都有两个子节点。满二叉树的高度为h,那么它的节点总数将是2^{h} - 1

如果一棵树是满二叉树,那么求出深度n后,满二叉树的节点数= 2^{n} -1

 故:首先判断一棵子树是否为满二叉树,如果是,根据深度求出节点数返回给上一层节点,如果不是,继续向下遍历,找出满二叉树(注:单个节点是满二叉树);最后根节点根据左子树数量+右子树数量+1,即为完全二叉树的节点个数;

如何判断是否为满二叉树:在完全二叉树的基础上,从某子树的根节点开始向左遍历的深度 = 向右遍历的深度;即为满二叉树,同时深度也已求出;

四、相关算法题目

111.二叉树的最小深度

class Solution {
    public int minDepth(TreeNode root) {
        //递归法
        return getHight(root);
    }
    public int getHight(TreeNode node){
        if(node == null){
            return 0;
        }else if(node.left == null && node.right == null){
            return 1;
        }else if(node.left == null && node.right != null){
            return 1 + getHight(node.right);
        }else if(node.left != null && node.right == null){
            return 1 + getHight(node.left);
        }else{
            int leftHight = getHight(node.left);
            int rightHight = getHight(node.right);
            int hight = Math.min(leftHight, rightHight);
            return 1 + hight;
        }
    }
}

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

 递归法

class Solution {
    public int countNodes(TreeNode root) {
        //递归法
        return getNum(root);
    }
    public int getNum(TreeNode node){
        if(node == null) return 0;
        int leftNum = getNum(node.left);
        int rightNum = getNum(node.right); 
        //getNum(node.left);
        //getNum(node.right);
        return 1 + leftNum + rightNum;
    }
}

迭代法:层序遍历

class Solution {
    public int countNodes(TreeNode root) {
        //层序遍历 队列统计 按照普通二叉树的求法之迭代法
        Deque<TreeNode> deque = new ArrayDeque<>();
        if(root == null) return 0;
        deque.offer(root);
        int count = 0;
        while(!deque.isEmpty()){
            TreeNode node = deque.poll();
            count++;
            if(node.left != null) deque.offer(node.left);
            if(node.right != null) deque.offer(node.right);
        }
        return count;
    }
}

完全二叉树特性

class Solution {
    public int countNodes(TreeNode root) {
        //完全二叉树特性
        return getNum(root);
    }
    public int getNum(TreeNode node){
        if(node == null) return 0;
        TreeNode leftNode = node.left;
        TreeNode rightNode = node.right;
        int leftDepth = 0;
        int rightDepth = 0;
        while(leftNode != null){
            //遍历左侧的深度
            leftNode = leftNode.left;
            leftDepth++;
        }
        while(rightNode != null){
            //遍历右侧的深度
            rightNode = rightNode.right;
            rightDepth++;
        }
        if(leftDepth == rightDepth){
            //说明是满二叉树
            return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
        }else{
            int left = getNum(node.left);
            int right = getNum(node.right);
            return 1 + left + right;
        }
    }
}

 五、总结

1.错误代码:当前代码的逻辑是直接取左右子树的最小深度加 1,但这种逻辑在某些情况下会出错。

class Solution {
    public int minDepth(TreeNode root) {
        //递归法
        return getHight(root);
    }
    public int getHight(TreeNode node){
        if(node == null) return 0;
        int leftHight = getHight(node.left);
        int rightHight = getHight(node.right);
        int hight = Math.min(leftHight, rightHight);
        return 1 + hight;
    }
}

错误原因:如果某个子树为空,这条路径不应该被考虑。所以应该分情况讨论

2. (2 << leftDepth) - 1

  • 2 << leftDepth 是位运算,等价于 2 * (2^leftDepth),即 2^(leftDepth + 1)

  • (2 << leftDepth) - 1 就是 2^(leftDepth + 1) - 1,即满二叉树的节点总数。

相关文章:

  • Java反射与动态代理:框架设计的基石
  • Spring WebFlux:响应式编程
  • 文字转语音chat-tts-ui
  • 分布式锁—Redisson的同步器组件
  • MySQL中 IN 到底走不走索引?
  • win10安装部署DB-gpt,坑多
  • mac使用Homebrew安装miniconda(mac搭建python环境),并在IDEA中集成miniconda环境
  • 20天 - TCP 和 UDP 有什么区别?说说 TCP 的三次握手?TCP 是用来解决什么问题?
  • Python中很常用的100个函数整理
  • React基础之类组件
  • XSENS:科幻电影《Love me》使用动作捕捉技术将未来AI拟人化
  • STM32初始安装
  • 2019年蓝桥杯第十届CC++大学B组真题及代码
  • Python 机器学习小项目:手写数字识别(MNIST 数据集)
  • Neo4j 数据库备份
  • 1分钟看懂React的那些Hook‘s
  • GaussDB安全配置指南:从认证到防御的全方面防护
  • 深入剖析顺序存储二叉树与线索化二叉树:数据结构的灵活转换与优化
  • 常用的gpt
  • 通过大视觉模型实现的多维方向性增强分割|文献速递-医学影像人工智能进展
  • 一周观展|一批重量级考古博物馆开馆:从凌家滩看到孙吴大墓
  • 一女游客在稻城亚丁景区因高反去世,急救两个多小时未能恢复生命体征
  • 网文书单|推荐4本网文,可以当作《绍宋》代餐
  • 解放日报:“感觉全世界人都在上海买买买”
  • 全国多家健身房女性月卡延长,补足因月经期耽误的健身时间
  • 3月中国减持189亿美元美债、持仓规模降至第三,英国升至第二