二叉树题目:平衡二叉树

news2024/11/25 23:14:36

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:平衡二叉树

出处:110. 平衡二叉树

难度

4 级

题目描述

要求

给定一个二叉树,判断它是否是高度平衡的二叉树。

这道题中,一个高度平衡二叉树定义为:二叉树中每个结点的左右两个子树的高度差的绝对值不超过 1 \texttt{1} 1

示例

示例 1:

示例 1

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

示例 2:

示例 2

输入: root   =   [1,2,2,3,3,null,null,4,4] \texttt{root = [1,2,2,3,3,null,null,4,4]} root = [1,2,2,3,3,null,null,4,4]
输出: false \texttt{false} false

示例 3:

输入: root   =   [] \texttt{root = []} root = []
输出: true \texttt{true} true

数据范围

  • 树中结点数目在范围 [0,   5000] \texttt{[0, 5000]} [0, 5000]
  • -10 6 ≤ Node.val ≤ 10 6 \texttt{-10}^\texttt{6} \le \texttt{Node.val} \le \texttt{10}^\texttt{6} -106Node.val106

解法一

思路和算法

只要得到二叉树中的每个子树的高度,即可判断二叉树是否高度平衡。

规定空二叉树的高度是 0 0 0,当二叉树非空时,二叉树的高度是从根结点到最深叶结点的路径上的结点数。

在得到二叉树中的每个子树的高度之后,即可判断二叉树中的每个子树是否高度平衡,并判断原始二叉树是否高度平衡。一个二叉树高度平衡,等价于其左子树和右子树的高度差的绝对值不超过 1 1 1,且左子树和右子树都高度平衡。

可以使用深度优先搜索实现,从根结点开始遍历每个结点,得到每个子树的高度并判断每个子树是否高度平衡。计算每个子树的高度和判断每个子树是否高度平衡的过程都是递归的过程。

计算每个子树的高度的递归终止条件是当前子树为空,此时高度是 0 0 0。对于其余情况,首先计算当前结点的左子树和右子树的高度,然后得到以当前结点为根结点的子树的高度是左子树和右子树的高度中的最大值加 1 1 1

判断每个子树是否高度平衡的的递归终止条件是当前子树为空,此时高度平衡。对于其余情况,根据左子树和右子树的高度差的绝对值是否不超过 1 1 1 以及左子树和右子树是否高度平衡判断当前子树是否高度平衡。

代码

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        return Math.abs(getHeight(root.left) - getHeight(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }

    public int getHeight(TreeNode node) {
        if (node == null) {
            return 0;
        }
        return Math.max(getHeight(node.left), getHeight(node.right)) + 1;
    }
}

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是二叉树的结点数。每个结点都被访问一次,计算每个子树高度的时间取决于二叉树的高度,最坏情况下计算每个子树高度的时间是 O ( n ) O(n) O(n),此时总时间复杂度是 O ( n 2 ) O(n^2) O(n2)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)

解法二

思路和算法

解法一的时间复杂度较高,因为存在重复计算每个子树的高度的情况。为了降低时间复杂度,应避免重复计算,确保每个子树的高度只计算一次。

由于这道题要求判断二叉树是否高度平衡,不需要知道二叉树的具体高度,因此可以在计算每个子树的高度时同步判断子树是否高度平衡。由于每个子树的高度一定是非负数,因此可以将高度记为 − 1 -1 1 表示一个子树高度不平衡。

计算每个子树的高度仍使用递归的方法。递归终止条件是当前子树为空,此时高度是 0 0 0,高度平衡。对于其余情况,首先计算当前结点的左子树和右子树的高度以及是否高度平衡,然后计算以当前结点为根结点的子树的高度,具体做法如下。

  1. 如果左子树和右子树的高度中存在 − 1 -1 1,则相应的子树高度不平衡,以当前结点为根结点的子树也高度不平衡,返回 − 1 -1 1

  2. 如果左子树和右子树都高度平衡,且左子树和右子树高度差的绝对值超过 1 1 1,则以当前结点为根结点的子树高度不平衡,返回 − 1 -1 1

  3. 如果左子树和右子树都高度平衡,且左子树和右子树高度差的绝对值不超过 1 1 1,则以当前结点为根结点的子树高度平衡,计算当前高度是左子树和右子树的高度中的最大值加 1 1 1,返回当前高度。

由于只有高度平衡的二叉树的高度才是非负数,因此可以根据原始二叉树的高度是否大于等于 0 0 0 判断原始二叉树是否高度平衡。

由于当一个子树高度不平衡时将 − 1 -1 1 作为其高度返回,不会再次递归地计算高度,因此上述做法可以确保每个子树的高度只计算一次,将时间复杂度降低到 O ( n ) O(n) O(n)

代码

class Solution {
    public boolean isBalanced(TreeNode root) {
        return getHeight(root) >= 0;
    }

    public int getHeight(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int heightLeft = getHeight(node.left);
        if (heightLeft < 0) {
            return -1;
        }
        int heightRight = getHeight(node.right);
        if (heightRight < 0) {
            return -1;
        }
        if (Math.abs(heightLeft - heightRight) > 1) {
            return -1;
        }
        return Math.max(heightLeft, heightRight) + 1;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点最多被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)

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

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

相关文章

生产者、消费者问题

线程六个状态&#xff1a; public enum State {/*** 新生*/NEW,/*** 运行*/RUNNABLE,/***阻塞*/BLOCKED,/*** 等待*/WAITING,/*** 超时等待*/TIMED_WAITING,/**死亡**/TERMINATED;} synchronized和lock的区别 1、synchronized是关键字&#xff0c;lock是类 2、synchronized全自…

蓝桥等考Python组别九级008

第一部分&#xff1a;选择题 1、Python L9 &#xff08;15分&#xff09; 运行下面程序&#xff0c;可以输出几行“*”&#xff1f;&#xff08; &#xff09; for i in range(8): for j in range(9): print(*, end ) print() 78910 正确答案&#xff1a;B 2、Python…

MySQL数据查询性能如何分析--Explain介绍说明

1、Explain是什么 Explain是MySQL执行查看执行计划命令的指令&#xff0c;使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 2、Explain官网介绍 http://dev.mysql.com/doc/refma…

MD5 绕过第三式:ffifdyop

文章目录 参考环境推荐阅读雾现两个 PHP 文件表结构分析 雾散ASCII 编码二进制数据到 ASCII 文本的转化绕过原理ffifdyop绕过 ffifdyop 的批量化生产批量化生产注意事项细节一字之差运算符优先级 实际需要遵守的规则 生产机器 参考 项目描述搜索引擎Bing、GoogleAI 大模型文心…

中国逐年干燥度指数数据集

简介&#xff1a; 中国逐年干燥度指数&#xff0c;空间分辨率为1km&#xff0c;时间为1901-2022&#xff0c;为比值&#xff0c;没有单位。该数据集是基于中国1km逐月潜在蒸散发&#xff08;PET&#xff09;和降水量&#xff08;PRE&#xff09;采用比值法计算式得到&#xff…

C#,数值计算——Ranhash的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// High-quality random hash of an integer into several numeric types. /// </summary> public class Ranhash { public Ranhash() { }…

Qt扩展-QCustomPlot 用户交互

QCustomPlot 用户交互 一、概述二、操作范围三、选择机制1. 控制Graph的可选择性和选择状态2. 所选对象的外观3. 多部分对象4. 对选择变化做出反应 四、用户交互信号 一、概述 QCustomPlot提供了多个内置的用户交互。它们大致可以分为 通过用鼠标拖动和滚动鼠标滚轮进行范围操…

Vue控制textarea可输入行数限制-案例

控制只能输入六行内容 UI部分代码 //我使用了antd ui库 <a-form-model-item ref"address_group" label"规则描述" prop"address_group" > <a-textarea:rows"6"style"width: 60%"placeholder"一次最多输入6行…

BUUCTF reverse wp 71 - 75

[NPUCTF2020]你好sao啊 int __cdecl main(int argc, const char **argv, const char **envp) {__int64 v3; // rax__int64 v4; // rdx__int64 v5; // raxsize_t v6; // rax__int64 v7; // rax__int64 v8; // rdx__int64 v9; // rax__int64 v11; // rdx__int64 v12; // raxchar …

AOP:分页参数统一校验

需求说明 为了保证系统的安全性&#xff0c;需要对所有的 查询列表 接口&#xff0c;添加分页参数&#xff0c;并对分页参数进行校验&#xff0c; &#xff0c;保证参数的合法性。 比如&#xff0c; pageSize&#xff08;每页显示条数&#xff09;&#xff0c;如果不做校验&a…

基于Java的个人博客文章管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

传统安防音视频平台架构

内部级联,为上下级均为自己平台海康子进程调用海康的设备SDKPTPCS通过封装代理不同的私有协议的差异,封装为大华统一的三代协议PC客户端通过调用平台SDKCMS一般采用双机热备技术PTPCS系统一般采用Windows嵌入式,由于部分设备厂家提供的SDK只有Windows的服务和服务之间的调用通过…

爱创科技携手源石酒庄,助力酒企走出窜货售假“沼泽”

在中国&#xff0c;一场关于美酒生活的消费革命正默默兴起。随着人们生活品质的不断提升&#xff0c;越来越多的消费者开始追求个性化、健康和美好的饮酒体验&#xff0c;消费升级正推动着酒行业整体逐步“迭代进化”。作为国内最早开始葡萄酒产业工业化发展的地区之一&#xf…

BUUCTF reverse wp 56 - 60

[ACTF新生赛2020]SoulLike __int64 __fastcall main(int a1, char **a2, char **a3) {char v5; // [rsp7h] [rbp-B9h]int i; // [rsp8h] [rbp-B8h]int j; // [rspCh] [rbp-B4h]int flag_content[14]; // [rsp10h] [rbp-B0h] BYREFchar flag[110]; // [rsp4Ah] [rbp-76h] BYREFu…

网络协议--概述

1.2 分层 网络协议通常分不同层次进行开发&#xff0c;每一层分别负责不同的通信功能。一个协议族&#xff0c;比如TCP/IP&#xff0c;是一组不同层次上的多个协议的组合。 TCP/IP通常被认为是一个四层协议系统&#xff0c;如图1-1所示。每一层负责不同的功能&#xff1a; 1.链…

从零手搓一个【消息队列】实现消息在文件中的存储

文章目录 一、序列化 / 反序列化二、文件存储设计1, 队列目录2, 消息数据文件3, 消息统计文件 三、硬盘管理 -- 文件1, 创建 MessageFileManager 类2, createQueueFiles() 创建目录/文件3, deleteFiles() 删除目录/文件4, checkFileExists() 检查目录/文件是否存在5, readStat(…

MonkeyRunner自动化测试

一&#xff1a;简介 MonkeyRunner提供了一个API&#xff0c;使用此API写出的程序可以在Android代码之外控制Android设备和模拟器。通过monkeyrunner&#xff0c;您可以写出一个Python程序去安装一个Android应用程序或测试包&#xff0c;运行它&#xff0c;向它发送模拟击键&…

单目标应用:基于狐猴优化算法(Lemurs Optimizer,LO)的微电网优化调度MATLAB

一、狐猴优化算法 狐猴优化算法&#xff08;Lemurs Optimizer&#xff0c;LO&#xff09;由Ammar Kamal Abasi等人于2022年提出&#xff0c;该算法模拟狐猴的跳跃和跳舞行为&#xff0c;具有结构简单&#xff0c;思路新颖&#xff0c;搜索速度快等优势。 狐猴头体长约为30-45…

【通意千问】大模型GitHub开源工程学习笔记(2)--使用Qwen进行推理的示例代码解析,及transformers的库使用

使用Transformers来使用模型 如希望使用Qwen-chat进行推理,所需要写的只是如下所示的数行代码。请确保你使用的是最新代码,并指定正确的模型名称和路径,如Qwen/Qwen-7B-Chat和Qwen/Qwen-14B-Chat 这里给出了一段代码 from transformers import AutoModelForCausalLM, Aut…

Promise击鼓传花

Promise击鼓传花 Promise系列导航前言一、Promise.prototype.then()1.语法2.代码及说明&#xff08;1&#xff09;代码段&#xff1a;&#xff08;2&#xff09;代码段&#xff1a;&#xff08;3&#xff09;代码段&#xff1a;&#xff08;4&#xff09;代码段&#xff1a;&am…