算法通关村—轻松搞定二叉树的高度和深度问题

news2024/11/26 20:40:33

1.二叉树的最大深度

二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

在这里插入图片描述

1.1 递归

在这里插入图片描述
通过上面的步骤能够看出,深度取决于左右子树,只要左子树有,那么高度就+1,或者有右子树,只需要将左右子树的高度算出来,然后比较高度再+1即可。

public int maxDepth(TreeNode root) {
        if(root==null) return 0;
        int leftHight = maxDepth(root.left);
        int rightHight = maxDepth(root.right);
        return Math.max(leftHight,rightHight)+1;
    }

在这里插入图片描述

1.2 层序遍历

相对简单,只需要每次遍历的时候,结果加1就可以,总体上还是层序遍历操作。

public int maxDepth(TreeNode root) {
        if(root==null) return 0;
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        // 计算深度
        int res =0 ;
        while(!queue.isEmpty()){
            // 每一层的元素数
            int size = queue.size();
            while(size>0){
                TreeNode node = queue.poll();
                if(node.left!=null){
                    queue.offer(node.left);
                }
                if(node.right!=null){
                    queue.offer(node.right);
                }
                size--;
            }
            res++;
        }
        return res;
    }

在这里插入图片描述

2. 平衡二叉树

平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

2.1 自顶向下递归

首先需要将二叉树分成左右两树,然后分别针对左右两树进行高度计算,只要有子节点,高度就+1。

    public boolean isBalanced(TreeNode root) {
        if(root == null) return true;
        // 左树的高度
        int leftHight =getTreeHight(root.left);
        // 右树的高度
        int rightHight =getTreeHight(root.right);
        // 判断高度差,递归
        return Math.abs(leftHight-rightHight)<=1 && isBalanced(root.left) && isBalanced(root.right);

    }
    // 获取当前节点的高度
    public int getTreeHight(TreeNode node){
        if(node == null) return 0;
        int leftHight = getTreeHight(node.left);
        int rightHight=getTreeHight(node.right);
        return Math.max(leftHight,rightHight)+1;
    }

在这里插入图片描述
一开始想使用层序遍历,没有考虑到是针对左右子树的情况,但是上面这种递归是采用的从上而下,计算所有的高度,时间复杂度:O(n^2),比较浪费性能。

2.2 自底向上递归

这种方式优点类似后序遍历,左右根的方式,最左边的元素在第一个,然后如果是有并排的同属一个树的右子树,或者当前没有右子树,那么认为是平衡的,然后继续递归,直到高度不符合,退出。

  public boolean isBalanced(TreeNode root) {
        return getTreeHight(root) >=0;
    }
    // 获取当前节点的高度
    public int getTreeHight(TreeNode root){
        if(root == null) return 0;
        int leftHight = getTreeHight(root.left);
        int rightHight = getTreeHight(root.right);
        // 不满足条件leftHight=-1标识没有左子树,rightHight=-1类似
        if(leftHight == -1 || rightHight == -1 || Math.abs(leftHight-rightHight)>1){
            return -1;
        }else{
            return Math.max(leftHight,rightHight)+1;
        }
    }

3. 二叉树的最小深度

二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
在这里插入图片描述
输入:root = [3,9,20,null,null,15,7]
输出:2

3.1 递归

首先左右孩子都为空,意味着是叶子节点,返回1
当左右节点有一个为空,就表示需要的深度就是另一个子树的深度+1
当左右节点都存在,就选取比较小的深度。

    public int minDepth(TreeNode root) {
      if(root == null) return 0;
      // 只有根节点,此时就是叶子节点
      if(root.left==null && root.right == null) return 1;
      // 左子树深度
      int leftLength = minDepth(root.left);
      // 右子树深度
      int rightLength = minDepth(root.right);
      // 树的深度:非空子树的深度加上根节点本身,只要有一个子树为空,那么其对应的深度就是0
      if(root.left == null || root.right == null) return leftLength+rightLength+1;
      // 左右子树都不为空,深度就是左右子树较小的加上本身
      return Math.min(leftLength,rightLength)+1;
    }

在这里插入图片描述

3.2 层序遍历

层序遍历就比较容易理解,只是需要判断是不是叶子节点,是叶子节点,就直接返回当前深度,不是那么就继续添加。

    public int minDepth(TreeNode root) {
     if(root ==null) return 0;
     LinkedList<TreeNode> queue = new LinkedList<>();
     queue.add(root);
     int minLength =0;
     while(!queue.isEmpty()){
       int size = queue.size();
        minLength++;
        for(int i=0;i<size;i++){
          TreeNode node =queue.remove();
          // 遇到叶子节点就返回
          if(node.left==null && node.right==null){
            return minLength;
          }

          if(node.left!=null){
            queue.add(node.left);
          }

          if(node.right!=null){
            queue.add(node.right);
          }
        }
     }
     return 0;
    }

在这里插入图片描述
相比于递归,层序遍历反而事件,空间比较快,因为只需要满足相应的树节点的子树都为空,就意味着找到了叶子节点,深度返回,最终一定会找到第一个叶子节点为空,那么就不需要遍历所有的二叉树了。

4. N 叉树的最大深度

N 叉树的最大深度
给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

4.1 层序遍历

这一题和二叉树类似,区别在于需要遍历子元素然后添加子元素。

 public int maxDepth(Node root) {
        if(root == null) return 0;
        LinkedList<Node> queue = new LinkedList<>();
        queue.add(root);
        int minLength = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            minLength++;
            for(int i=0;i<size;i++){
                Node node = queue.poll();
               List<Node> children = node.children;
               for(Node child:children){
                   queue.add(child);
               }
            }
        }
        return minLength;
    }

在这里插入图片描述

4.2 递归

    public int maxDepth(Node root) {
        if(root == null) 
            {return 0;}
        else if(root.children.isEmpty()) 
            {return 1;}
        else{
            List<Integer> hight = new ArrayList<>();
            List<Node> children = root.children;
            for(Node child:children){
                hight.add(maxDepth(child));
            }
            return Collections.max(hight)+1;
        }
    }

总结

关于二叉树的深度和高度问题,使用递归是很快速的,但是缺点在于需要考虑好边界,有的时候感觉想不到递归的解决方案,递归还是不大熟,而层序遍历容易理解和想到,但是缺点在于代码比较长。

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

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

相关文章

java泛型和通配符的使用

泛型机制 本质是参数化类型(与方法的形式参数比较&#xff0c;方法是参数化对象)。 优势:将类型检查由运行期提前到编译期。减少了很多错误。 泛型是jdk5.0的新特性。 集合中使用泛型 总结&#xff1a; ① 集合接口或集合类在jdk5.0时都修改为带泛型的结构② 在实例化集合类时…

每日一学:什么是 Harbor ?

目录 什么是 Harbor &#xff1f; 一、Harbor 的优势 二、Harbor 架构构成 三、Core services 这是 Harbor 的核心功能 什么是 Harbor &#xff1f; Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的 Docker Reg…

【论文阅读】EULER:通过可扩展时间链接预测检测网络横向移动(NDSS-2022)

作者&#xff1a;乔治华盛顿大学-Isaiah J. King、H. Howie Huang 引用&#xff1a;King I J, Huang H H. Euler: Detecting Network Lateral Movement via Scalable Temporal Graph Link Prediction [C]. Proceedings 2022 Network and Distributed System Security Symposium…

虹科分享 | 新时代“救命神器”:看AR眼镜如何应用于紧急救险场景

从工业时代到如今迎来的“体验时代”&#xff0c;体验即内容&#xff0c;5G、AI、空间计算技术的突破&#xff0c;为各行各业创建了丰富的内容体验模式&#xff0c;让人们能够听之、触之、与之交互。AR是体验时代最具潜力的新技术&#xff0c;在“应急”场景中更是成为了我们在…

政府大数据资源中心建设总体方案[56页PPT]

导读&#xff1a;原文《政府大数据资源中心建设总体方案[56页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需…

字节大佬教你Python接口自动化测试(项目实战),一篇足矣

接口自动化测试是指通过编写程序来模拟用户的行为&#xff0c;对接口进行自动化测试。Python是一种流行的编程语言&#xff0c;它在接口自动化测试中得到了广泛应用。下面详细介绍Python接口自动化测试实战。 我也在文末准备的学习资料以及配套的视频教程&#xff0c;需要视频…

解读新东方Q4财报:银发经济能否造就下一个“东方甄选”?

8月1日下午&#xff0c;关停多日的东方甄选自营店铺抖音账号重新开播。尽管停播了26日至29日四天&#xff0c;但似乎并未产生太大影响。据东方甄选披露&#xff0c;7月29日的单日销售额已高达3500万元。 东方甄选长期稳定发展也使新东方受益。在“东方甄选自营产品”的抖音直播…

并查集维护额外信息,算法思路类似前缀和,结构类似扑克接龙

一、链接 240. 食物链 二、题目 动物王国中有三类动物 A,B,CA,B,C&#xff0c;这三类动物的食物链构成了有趣的环形。 AA 吃 BB&#xff0c;BB 吃 CC&#xff0c;CC 吃 AA。 现有 NN 个动物&#xff0c;以 1∼N1∼N 编号。 每个动物都是 A,B,CA,B,C 中的一种&#xff0c;…

C++ 运算符重载为成员函数

运算符重载实质上就是函数重载&#xff0c;重载为成员函数&#xff0c;他就可以自由访问本类的数据成员。实际使用时&#xff0c;总是通过该类的某个对象来访问重载的运算符。 如果是双目运算符&#xff0c;左操作数是对象本身的数据&#xff0c;由this指针指出&#xff0c;右…

1. 软件生命周期C/S、B/S 架构

目录 1. 软件生命周期 2. 面向对象 2.1 面向对象分析 2.2 面向对象设计 2.3 面向对象编程 3. C/S、B/S 架构 3.1 CS 架构 3.2 BS 架构 1. 软件生命周期 软件生命周期中划分为可行性研究、需求分析、概要设计、详细设计、实现、组装(集成)测试、 确认测试、使用、维护…

【Linux】进程间通信——system V共享内存

目录 写在前面的话 System V共享内存原理 System V共享内存的建立 代码实现System V共享内存 创建共享内存shmget() ftok() 删除共享内存shmctl() 挂接共享内存shmat() 取消挂接共享内存shmdt() 整体通信流程的实现 写在前面的话 上一章我们讲了进程间通信的第一种方式…

kubeadml 安装 k8s

目录 一&#xff1a;kubeadml 安装 k8s 1、网络环境 2、 环境准备 3、 所有节点安装docker 4、所有节点安装kubeadm&#xff0c;kubelet和kubectl ​5、部署K8S集群 6、测试 二&#xff1a; 部署 Dashboard 一&#xff1a;kubeadml 安装 k8s 1、网络环境 master&am…

VBA遍历Wrod所有表格每个单元格,单元格未尾两个回车替换

一、遍历 word中遍历所有表格的每个单元格。因为在单元格时会常出错。浪费了不少时间。 Sub a()Dim doc As Document, tb As Table, ce As cellDim rng As Range, p As ParagraphSet doc ActiveDocumentFor Each tb In doc.TablesFor Each ce In tb.Range.Cells 关键处就是这里…

作为程序猿,怎么维护自己的电脑?

我的电脑是联想拯救者R7000 内存&#xff1a;16G CPU &#xff1a;AMD R5 外存&#xff1a;500G。买这台电脑是个意外。情况是这样的&#xff0c;面试去了一家外包公司&#xff0c;入职当天&#xff0c; HR问我&#xff1a;你的电脑呢&#xff1f; 我&#xff1a;没有发给我啊 …

十一、ESP32加快240x240显示二维码

1. 效果 非常快速的显示出二维码 2. 原理 2.1 之前的方式(慢)

MySQL日期常见的函数

-- 获取当天日期 -- 2023-06-20 select curdate();-- 获取当天年月日时分秒 select now();-- 日期运算 -- 2024-06-20 17:04:17 select date_add(now(),interval 1 year);-- 日期比较 -- 0 select datediff(now(),now());-- 日期MySQL对于日期类型数据如何查询 -- 获取指定日期…

vcode开发go

配置环境变量 go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct 创建文件夹 mkdir hello cd hello go mod init hello 安装所有"all" matched packages go mod tidy

Linux文件属性与权限管理(可读、可写、可执行)

Linux把所有文件和设备都当作文件来管理&#xff0c;这些文件都在根目录下&#xff0c;同时Linux中的文件名区分大小写。 一、文件属性 使用ls -l命令查看文件详情&#xff1a; 1、每行代表一个文件&#xff0c;每行的第一个字符代表文件类型&#xff0c;linux文件类型包括&am…

Python编程从入门到实践练习第五章:if语句和条件测试

目录 一、条件测试1.1 检测多个条件&#xff08;and / or&#xff09;1.2 检测特定值是否包含在列表中1.3 if语句结构 二、if语句处理列表2.1 判断列表是否为空2.2 练习题代码输出 一、条件测试 1.1 检测多个条件&#xff08;and / or&#xff09; 所用关键词 and : 两个条件…

C++ 多态 虚函数表

文章目录 简易抽象理解多态多态的具体实现虚函数的定义虚函数的重写重定义&#xff08;隐藏&#xff09;、重载 、重写&#xff08;覆盖&#xff09;区别C11 override 和 final 关键字抽象类的定义接口继承和实现继承多态的原理&#xff1a;虚函数表单继承和多继承关系的虚函数…