代码随想录:二叉树11-12

news2025/1/14 18:22:36

目录

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

题目

代码(层序迭代)

代码(后序递归)

代码(满二次树递归)

总结

110.平衡二叉树

题目

代码(后序递归)

代码(层序迭代)

代码(前序迭代)

总结


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

题目

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

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

示例 1:

输入:root = [1,2,3,4,5,6]
输出:6

代码(层序迭代)

class Solution {
    public int countNodes(TreeNode root) {

        //用层序迭代递归计算
        int size = 0; //初始大小为0
        Queue<TreeNode> que = new ArrayDeque<>();

        if(root == null){
            return 0;
        }

        que.offer(root);

        while(!que.isEmpty()){
            int len = que.size();  //获取当前层的节点个数
            size += len;  //更新size
            //当前层节点一个个出队
            while(len-- > 0){
                TreeNode cur = que.poll();
                //处理左右孩子,进队
                if(cur.left != null){
                    que.offer(cur.left);
                }
                if(cur.right != null){
                    que.offer(cur.right);
                }
            }
        }
        return size;
        

    }
}

代码(后序递归)

class Solution {
    public int countNodes(TreeNode root) {
        //用后序递归遍历计算
        //终止条件
        if(root == null){
            return 0;
        }
        //单层逻辑
        int left = countNodes(root.left); //计算左子树节点数量(左)
        int right = countNodes(root.right); //计算右子树节点数量(右)
        int result = left + right + 1; //中
        return result;

    }
}

代码(满二次树递归最难理解)

class Solution {
    //用完全二叉树的性质递归计算,时间复杂度小于o(n)
    //核心原理是如果是满二叉树,左右侧深度一样,可以2^depth-1直接计算,不用全部遍历
    public int countNodes(TreeNode root) {
        //终止条件1
        if(root == null){
            return 0;
        }
        //终止条件2,是满二叉树,可以直接根据深度计算节点数
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftdepth = 0;
        int rightdepth = 0;
        //左孩子一直往左下走,计算左下深度
        while(left != null){
            left = left.left;
            leftdepth++;
        }
        //右孩子一直往右下走,计算右下深度
        while(right != null){
            right = right.right;
            rightdepth++;
        }
        //如果左右深度一样,说明是满二叉树,直接计算返回
        if(leftdepth == rightdepth){
            //按注释计算2^depth-1 力扣上不知道为什么通不过
            //return ((int)Math.pow(2,leftdepth) - 1);
            return (2 << leftdepth) - 1;
        }

        //单层逻辑
        int l = countNodes(root.left); //计算左孩子节点数(左)
        int r = countNodes(root.right); //计算右孩子节点数(右)
        int result = l + r + 1; //中
        return result;
    }
}

总结

        层序迭代和后序递归的核心逻辑很简单,就是用普通的遍历二叉树的方法,一边遍历一边计算节点数,即在原先的遍历代码中加上计算节点数的代码即可。时间复杂度是o(n)。

        满二叉树递归的核心逻辑,利用了满二叉树的性质,如果一个子树的满二叉树,从根节点往左和往右的最大深度是一样的。因此我们通过前序递归遍历二叉树,如果当前节点时满二叉树(终止条件),就可以直接计算节点数是2^depth-1,不用继续遍历其孩子节点。如果不是满二叉树(单层逻辑),就继续前序遍历下去,不是满二叉树的节点数=左子树节点+右子树节点+1。时间复杂度<=o(n)。

110.平衡二叉树

题目

给定一个二叉树,判断它是否是平衡二叉树

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:true

代码(后序递归最难理解)

class Solution {
    //后序递归判断
    public boolean isBalanced(TreeNode root) {
        int result = postOrder(root);
        if(result == -1){
            return false;
        }
        else{
            return true;
        }

    }
    //后序遍历,判断每个节点是否满足高度差<=1
    //返回值int有两层意思:如果=-1代表当前节点不平衡,如果不是-1,代表当前节点的高度
    public int postOrder(TreeNode root){
        //终止条件1
        if(root == null){
            return 0;
        }
        //计算当前节点的左右孩子高度
        int leftheight = postOrder(root.left); //左子树高度
        int rightheight = postOrder(root.right); //右子树高度
        //终止条件2,左子树不平衡
        if(leftheight == -1){
            return -1;
        }
        //终止条件3,右子树不平衡
        if(rightheight == -1){
            return -1;
        }
        //终止条件4,左右子树高度差大于1
        if(Math.abs(leftheight - rightheight) > 1){
            return -1;
        }
        //单层循环
        //如果该节点满足平衡二叉条件,计算该节点的高度,继续递归判断
        int result = 1 + Math.max(leftheight,rightheight);
        return result;

    }
}

代码(层序迭代)

class Solution {
    //层序迭代判断,核心逻辑是层序遍历每个节点,判断是否满足平衡条件
    public boolean isBalanced(TreeNode root) {
        //层序遍历节点,逐个判断该节点是否满足高度差<=1
        Queue<TreeNode> que = new ArrayDeque<>();

        if(root == null){
            return true;
        }

        que.offer(root);

        while(!que.isEmpty()){
            int size = que.size();
            //处理当前层的所有节点
            while(size-- > 0){
                TreeNode cur = que.poll();
                //计算cur的左右孩子的高度
                int leftheight = getheight(cur.left);
                int rightheight = getheight(cur.right);
                //如果高度差>1,不满足平衡直接return
                if(Math.abs(leftheight - rightheight) > 1){
                    return false;
                }
                if(cur.left != null){
                    que.offer(cur.left);
                }
                if(cur.right != null){
                    que.offer(cur.right);
                }
            }
        }
        return true;
    }
    //计算cur节点的高度
    public int getheight(TreeNode cur){
        //终止条件
        if(cur == null){
            return 0;
        }
        //单层逻辑
        int left = getheight(cur.left);
        int right = getheight(cur.right);
        return 1 + Math.max(left,right);
    }
}

代码(前序迭代)

class Solution {
    
    public boolean isBalanced(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        if(root == null){
            return true;
        }
        //前序迭代遍历每一个节点,并判断该节点是否平衡
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur = stack.pop();
            //计算当前cur节点的左右高度
            int leftheight = getheight(cur.left);
            int rightheight = getheight(cur.right);
            //如果cur不平衡,直接返回false
            if(Math.abs(leftheight - rightheight) > 1){
                return false;
            }
            if(cur.right != null){
                stack.push(cur.right);
            }
            if(cur.left != null){
                stack.push(cur.left);
            }
        }
        //遍历完全部节点,都满足平衡,就返回true
        return true;
        
    }
    
    //计算cur节点的高度
    public int getheight(TreeNode cur){
        //终止条件
        if(cur == null){
            return 0;
        }
        //单层逻辑
        int left = getheight(cur.left);
        int right = getheight(cur.right);
        return 1 + Math.max(left,right);
    }
}

总结

        迭代法的逻辑很简单,就是用前序、层序遍历每一个节点时,同时计算当前节点的左右孩子高度,判断当前节点的高度差是否满足平衡,如果不满足,直接返回false,如果当前节点满足,再迭代判断后面的节点。最后,如果所有节点遍历完,都没有返回false,说明二叉树的每一个节点都满足平衡条件,就返回true。

        递归法,核心逻辑是一边后序递归二叉树,一边计算当前节点的左右孩子高度,判断当前遍历节点是否满足平衡,如果不满足平衡就返回-1,如果满足平衡就计算当前节点的高度。

         递归法有四个终止条件,一是节点为null,返回0。二是节点的左右高度差>1,返回-1。还有两种情况千万不能漏,如果该节点的左孩子or右孩子的返回值=-1,说明其左孩子or右孩子已经不平衡了,直接返回-1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1609127.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关基网络战时代,赛宁网安电力网络攻防靶场全面提升电网安全防护力

随着网络空间成为与陆地、海洋、天空、太空同等重要的人类活动新领域&#xff0c;自网络空间向物理电网发起攻击&#xff0c;破坏电力等国家关键基础设施成为当前大国博弈、大规模战争的重要手段和常态进攻形式。同时&#xff0c;新型电力系统建设发展驱动电力系统形态和控制方…

nginx installed inLinux

yum install nginx [rootmufeng ~]# yum install nginx CentOS系列&#xff1a;【Linux】CentOS7操作系统安装nginx实战&#xff08;多种方法&#xff0c;超详细&#xff09; ———————————————— 版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC …

LLAMA 3的测试之旅:在GPT-4的阴影下前行

Meta终于发布了他们长期期待的LLAMA 3模型&#xff0c;这是一个开源模型&#xff0c;实际上提供了一系列新的功能&#xff0c;使得模型在回答问题时表现得更好。这对AI社区来说是一个真正的里程碑事件。 Meta正在发布新版本的Meta AI&#xff0c;这是一种可以在他们的应用程序和…

原型和原型链--图解

https://juejin.cn/post/7255605810453217335 prototype是函数的属性&#xff08;一个对象&#xff09;&#xff0c;不是对象的属性&#xff0c;普通函数和构造函数的prototype属性是空对象&#xff5b;&#xff5d;&#xff08;其实有2个属性&#xff0c;一个是constructor&a…

PVE grub resue错误修复 lvmid BUG

服务器断电后启动不起来&#xff0c;显示grub resue 找了半天没有找到修复方法。看官方文档有一处Recovering from grub “disk not found” error when booting from LVM 极为类似。https://pve.proxmox.com/wiki/Recover_From_Grub_Failure 下面是处理过程。 使用PVE 6.4启…

汽车研发项目进度管理的挑战与优化策略

随着汽车行业的快速发展和市场竞争的加剧&#xff0c;新车型研发项目的进度管理成为车企赢得市场的关键。然而&#xff0c;由于汽车研发项目通常具有投资大、周期长、技术难度高、参与方众多等特点&#xff0c;项目进度管理面临着诸多挑战。为了提升车型研发效率、缩短研发周期…

数据结构|树形结构|并查集

数据结构|并查集 并查集 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 有趣的并查集剧情演绎&#xff1a;【算法与数据结构】—— 并…

多个路由器连接的PC端进行ping通信需要做的事

实验环境&#xff1a; 三台PC三台路由器&#xff0c;并且配置好IP 拓扑图&#xff1a; 需求描述&#xff1a; 在PC0进行与PC2的ping通信&#xff1a; 需求步骤&#xff1a; 1.1首先配置ip&#xff08;略过&#xff09; 1.2我们首先查看在只配置了IP的情况下&#xff0c;P…

跨境电商指南:防关联浏览器和云主机有什么区别?

跨境电商的卖家分为独立站卖家和平台卖家。前者会自己开设独立站点&#xff0c;比如通过 shopify&#xff1b;后者则是入驻亚马逊或 Tiktok 等平台&#xff0c;开设商铺。其中平台卖家为了扩大收益&#xff0c;往往不止开一个店铺&#xff0c;或者有店铺代运营的供应商&#xf…

java音乐播放器系统设计与实现springboot-vue

后端技术 SpinrgBoot的主要优点有&#xff1a; 1、为所有spring开发提供了一个更快、更广泛的入门体验&#xff1b; 2、零配置&#xff1b; 3、集成了大量常用的第三方库的配置&#xff1b; Maven: 项目管理和构建自动化工具&#xff0c;用于java项目。 java: 广泛使用的编程语…

Docker Desktop打开一直转圈的解决办法

安装Docker Desktop之前确保你的Hyper-V已经打开 开启后需要重新安装重新安装重新安装这是最关键的一步&#xff0c;博主自己看了很多教程&#xff0c;最后试着重装了一下解决了 安装DockerDesktop的时候我的电脑根本就没有Hyper-V这个功能选项&#xff0c;可能是这个问题 如…

鸿蒙系列--ArkTS

一、ArkUI开发框架 ArkUI框架提供开发者两种开发方式&#xff1a;基于ArkTS的声明式开发范式和基于JS扩展的类Web开发范式。声明式开发范式更加简洁&#xff0c;类 Web 开发范式对 Web 及前端开发者更友好 二、ArkTS声明式开发范式 对比类 Web 开发范式代码更为精简&#xf…

Redis中的Lua脚本(五)

Lua脚本 脚本复制 复制EVALSHA命令 EVALSHA命令式所有与Lua脚本有关的命令中&#xff0c;复制操作最复杂的一个&#xff0c;因为主服务器与从服务器载入Lua脚本的情况可能有所不同&#xff0c;所以主服务器不能像复制EVAL命令、SCRIPT LOAD命令或者SCRIPT FLUSH命令那样&…

TaskWeaver使用记录

TaskWeaver使用记录 1. 基本介绍2. 总体结构与流程3. 概念细节3.1 Project3.2 Session3.3 Memory3.4 Conversation3.5 Round3.6 Post3.7 Attachment3.8 Plugin3.9 Executor 4. 代码特点5. 使用过程5.1 api调用5.2 本地模型使用5.3 添加插件 6. 存在的问题与使用体验6.1 判别模型…

C语言 | Leetcode C语言题解之第40题组合总和II

题目&#xff1a; 题解&#xff1a; int** ans; int* ansColumnSizes; int ansSize;int* sequence; int sequenceSize;int** freq; int freqSize;void dfs(int pos, int rest) {if (rest 0) {int* tmp malloc(sizeof(int) * sequenceSize);memcpy(tmp, sequence, sizeof(int…

Web前端 JavaScript笔记7

js的执行机制 js是单线程 同步&#xff1a;前面一个任务执行结束之后&#xff0c;执行后一个 异步&#xff1a;异步任务&#xff0c;引擎放在一边&#xff0c;不进入主线程&#xff0c;而进入任务队列的任务 js通过浏览器解析&#xff0c;浏览器靠引擎解析 回调函数同步任务执行…

锂电池寿命预测 | Matlab基于GRU门控循环单元的锂电池寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 锂电池寿命预测 | Matlab基于GRU门控循环单元的锂电池寿命预测 Matlab基于GRU的锂电池剩余寿命预测 基于GRU的锂电池剩余寿命预测&#xff08;单变量&#xff09; 运行环境Matlab2020及以上 锂电池的剩余寿命预测是…

探索早期投资的奥秘:符文(Runes)生态系统的崛起

随着加密市场的迅速发展&#xff0c;投资者们对早期项目的关注越来越高。在这个充满变数和机遇的领域里&#xff0c;抢占先机意味着可能获得巨大的回报。符文&#xff08;Runes&#xff09;生态系统作为近期备受瞩目的项目之一&#xff0c;引发了众多投资者的兴趣。本文将深入探…

Java数据结构-二叉树

目录 1. 树与二叉树1.1 树1.2 二叉树1.3 树的相关概念1.4 特殊的二叉树1.5 二叉树性质1.6 二叉树的存储与表示方法 2. 二叉树遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 3. 二叉树基本操作3.1 求树的所有结点个数3.2 求叶子结点个数3.3 求第k层结点个数3.4 求二叉树…

笔记-----BFS宽度优先搜索

对于BFS&#xff1a;宽搜第一次搜到就是最小值&#xff0c;并且基于迭代&#xff0c;不会爆栈。 Flood Fill 模型 如果直译的话就是&#xff1a;洪水覆盖&#xff0c;意思就是像是从一个点一圈圈的往外扩散&#xff0c;如果遇见能够连通的就扩散&#xff0c;如果遇见无法联通的…