【数据结构二叉树OJ系列】6、平衡二叉树

news2024/9/25 1:25:50

 

 

目录

题述:

思路:

 正确代码如下:

时间复杂度分析:

现让你把代码优化时间复杂度为O(N)

思路:


题述:

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

本题中,一颗高度平衡二叉树的定义为:

一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1

示例1:

输入:root = 【3,9,20,NULL,NULL,15,7】

输出:true

 题中已给:

struct TreeNode
{
	int val;
	struct TreeNode* left;
	struct TreeNode* right;
};

bool isBalanced(struct TreeNode* root)

思路:

利用之前讲过的求树的深度的函数TreeDepth来求解这道题,根,左子树,右子树不断往下遍历,左子树又分为根,左子树,右子树,右子树又分为根,左子树,右子树直到遇到空树,对于每一个树都求一下左右子树的深度,然后判断一下树的高度是否>1,>1则不满足,<1则继续递归遍历,直到整棵树判断完毕,才可确定是平衡二叉树整体思路类似于根左右,即先判断当前树,再判断左子树,再判断右子树

 正确代码如下:


int TreeDepth(struct TreeNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int leftDepth = TreeDepth(root->left);
	int rightDepth = TreeDepth(root->right);

	return leftDepth > rightDepth ? leftDepth + 1
		: rightDepth + 1;
}

bool isBalanced(struct TreeNode* root)
{
    //空树满足平衡二叉树的定义
	if (root == NULL)
	{
		return true;
	}
    
    //先判断当前树是否满足
	int gap = TreeDepth(root->left) - TreeDepth(root->right);
	gap = abs(gap);//取绝对值

	if (gap > 1)
	{
		return false;
	}
    //再判断左右子树是否满足
	return isBalanced(root->left)
		&& isBalanced(root->right);
}

时间复杂度分析:

假设该二叉树有N个结点。

TreeDepth函数是把整个二叉树遍历了一遍,故时间复杂度:O(N)

对于isBalanced函数,它的遍历是根左右,下面给个二叉树方便说明这个问题

①、先会判断当前树(以3为根节点的树)左右深度的差的绝对值,这一次就遍历了一遍树,次数为N

②、再判断左子树(以9为根节点的树)左右深度的差的绝对值,也就是以9为根节点的左右子树的高度要再求一遍,为什么是“再”求以3为根节点的左子树的深度时,已经算过以9为根结点的树的深度了,所以先序遍历存在重复的深度计算。

那这种方法的时间复杂度:以3为根节点为N次,以其它节点为根节点均为N-常数次,总的时间复杂度加起来大概可以构成等差数列(N+N-常数+N-常数...),由等差数列前n项和公式:

N(N+N-常数) / 2 = O(N*N)

现让你把代码优化时间复杂度为O(N)

思路:

上面的代码时间复杂度慢在树的深度的重复计算,我们只要让树的深度算一遍就可以使时间复杂度优化到O(N)了,怎么做到深度只算一遍?即利用后序遍历:左右根,先判断左子树再判断右子树最后再判断当前树。我们不调用TreeDepth函数,而是每次在判断是否是平衡二叉树的同时,返回当前树的深度给上层(递归往回返的过程)。那就意味着深度和是否为平衡二叉树(返回真假)每次都要返回,法一:考虑返回结构体,结构体包含这两个。法二:参数传深度的地址,每次调用在需要改的时候改,函数返回真假。

bool isBalanced(struct TreeNode* root, int * depth)
{
	//如果为空树
	if (root == NULL)
	{
		*depth = 0;
		return true;
	}

	//先判断左子树
	int leftdepth = 0;
	if (isBalanced(root->left, &leftdepth) == false)
		return false;
	int rightdepth = 0;
	if (isBalanced(root->right, &rightdepth) == false)
		return false;
	//再判断当前树,当前树是否满足平衡二叉树,看左右子树高度差的绝对值是否>1
	if (abs(leftdepth - rightdepth) > 1)
		return false;
	//左右子树,当前树都满足平衡二叉树的前提下
	*depth = leftdepth > rightdepth ? leftdepth + 1
		: rightdepth + 1;
	return true;

}

 

 以此二叉树为例,上述代码的执行过程如下:

①、root=3时,判断左子树,转为root=9,判断左子树,左子树为NULL,故9的左子树深度为0,return true,同理9的右子树深度为0,return true。再判断以9为根节点的当前树,深度差不>1,故高度为0+1=1,return true,至此算出以9为根节点的深度为1,并判断为满足平衡二叉树。

②、再判断root=3时的右子树,转为root=20,判断左子树,转为root=15,判断它的左子树, 为NULL,故15的左子树深度为0,return true,同理,15的右子树的深度为0,return true。再判断以15为根节点的当前树,深度差不>1,故高度为0+1=1,return true,至此算出以15为根节点的深度为1,并判断为满足平衡二叉树。

③、再判断20的右子树,同理上面,以7为根节点的深度为1,并判断为满足平衡二叉树。至此,20的左右子树判断完毕,再判断以20为根节点的当前树,深度差不>1,故深度为1+1=2,return true,至此算出以20为根节点的深度为2,并判断为满足平衡二叉树。

④、至此3的左右子树判断完毕,再判断以3为根节点的当前树,深度差不>1,故深度为2+1=3,return true,至此算出以3为根节点的深度为3,并判断整棵树满足平衡二叉树。

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

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

相关文章

HttpRunner自动化之接口关联和常用断言

接口关联 第一个test接口获取token,并提取出存储到变量中&#xff0c;在第二个test接口中直接调用该变量&#xff0c;如下图 # 接口关联 - config:name: 微信接口base_url: https://api.weixin.qq.com - test:name: 获取tokenrequest:url: /cgi-bin/tokenmethod: GETparams:g…

在vue3项目中加载Cesium立体地形信息并调整初始化角度

在vue3项目中加载Cesium立体地形信息并调整初始化角度 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium vite -D配置 &#xff08;1&#xff09;在项目的vite.config.js文件中添加&#xff1a; impo…

Java模拟cookie登陆操作

Java模拟cookie登陆操作 在使用java访问URL时&#xff0c;如果该URL需要身份验证&#xff0c;那么就不能够直接访问&#xff0c;因为没有登陆。那么&#xff0c;如何解决这个问题呢&#xff1f; 方法是使用java模拟登陆&#xff0c;登陆后记录下cookie信息&#xff0c;在下次发…

【算法集训之线性表篇】Day 07

文章目录 题目基本设计思想代码实现效果 题目 一个长度为L(L>1)的升序序列S&#xff0c;处在第[L/2]个位置的数称为S的中位数。例如&#xff0c;若序列S1{11,13,15,17,19},则S1的中位数是15&#xff0c;两个序列的中位数是含它们所有元素的升序序列的中位数&#xff0c;例如…

使用ida pro反编译并修改so库

快速搜索 图表视图 找到需要修改的行 Edit -> Patch program -> change byte… 复制指令 到这个网站Online ARM to HEX 点击可以切换为HEX to ARM 构造待修改的指令 修改好后复制HEX字符串 Edit -> Patch program -> Apply patches to input file

测试工程师的个人年终总结报告模板

目录 正文之前的思考&#xff1a; 年终总结报告 开篇语 1.  项目概述 1.1  项目情况 1.2  工作流程 1.3  个人角色 1.4  完成情况 2.  工作业绩 3.  亮点和不足 4.  未来展望 总结&#xff1a; 正文之前的思考&#xff1a; 开始编排文档之前来做一个…

FAM NHS ester,5-FAM azide,两者用于标记核苷酸的荧光试剂

一、FAM NHS ester,6-isomer&#xff0c;92557-81-8 理论分析&#xff1a; 中文名&#xff1a;羧基荧光素-活性酯&#xff0c;6-异构体&#xff0c;6-羧基荧光素琥珀酰亚胺酯,6-羧基荧光素-活性酯 英文名&#xff1a;FAM NHS ester,6-isomer&#xff0c;6-FAM-NHS&#xff0c;…

D. Survey in Class

D. Survey in Class Problem - D - Codeforces 思路&#xff1a;题目要求的是最大值与最小值的差值最大&#xff0c;那么我们能够想到&#xff0c;一定是两个人比较得到的最大的差值&#xff0c;假设a与b比较得到的最大的差值&#xff0c;因为如果提问了这两个区间都不包含的&…

单个电源模块带电感的直流压降仿真(二)

单个电源模块带电感的直流压降仿真(二) 接 单个电源模块带电感的直流压降仿真(一) 在右侧net manager disable all nets鼠标移动到需要仿真的电感前后两端的铜皮上,select net and enable net并且把GND也select和enable上

ceph用户认证

Cephx认证机制 ceph使用cephx协议对客户端进行身份认证 cephx用于对ceph保存的数据进行认证访问和授权&#xff0c;用于对访问ceph的请求进行认证和授权检测&#xff0c;于mon通信的请求都要经过ceph认证通过&#xff0c;但是也可以在mon节点关闭cephx认证&#xff0c;但是关…

微信小程序的目录结构及页面结构的说明

微信小程序的目录结构及页面结构的说明 1. 项目结构2.小程序的页面组成部分3.项目结构和页面结构文件的一些说明3.1. json文件3.2. wxml和wxss3.2.1. wxml3.2.2. wxss 3.2.3. 小程序中的.js文件 4. 微信小程序的宿主环境及运行机制4.1. 宿主环境4.2. 运行机制4.2.1. 小程序启动…

运营规模突破5万台,绿色慧联启动「望岳计划」!

狙击冲锋问鼎&#xff01;7月7日&#xff0c;绿色慧联“望岳计划”在杭州正式启动。远程新能源商用车集团副总裁兼绿色慧联总经理杨东及运营平台各职能部门、区域运营中心负责人共同参加了会议。 今年绿色慧联正面临更加多变的内外部市场环境&#xff0c;电池原材料价格下滑和整…

华为OD机试真题 Java 实现【宜居星球改造计划】【2023 Q2 200分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 大家好&#xff0c;我是哪吒。 做技术&#xff0c;我是认真的&#xff0c;立志于打造最权威的华为OD机试真题专栏&#xff0c;帮助那些与我有同样需求的人&#xff0…

eclipse安装

下载 https://www.eclipse.org/ 安装 选择web开发 启动项目&#xff0c;让选择工作地址 创建java web项目 选择一下运行时 选择好tomcat服务器finish即可 创建maven项目

Mybatis 学习笔记1:构造方法注入

Mybatis 构造方法注入 最近阅读 Mybatis 3.5.8-SNAPSHOT 版本源码&#xff0c;在调试过程中遇到如下异常&#xff1a; org.apache.ibatis.builder.BuilderException:Error in result map MyEmployee.empResultMap.Failed to find a constructor in MyEmployee by arg names […

python基于flask企业会议交换机设备维修批量运维管理系统设计与实现6py09

Python 中存在众多的 Web 开发框架&#xff1a;Flask、Django、Tornado、Webpy、Web2py、Bottle、Pyramid、Zope2 等。近几年较为流行的&#xff0c;大概也就是 Flask 和 Django 了解决的思路&#xff1a; &#xff08;1&#xff09;通过进行需求分析&#xff0c;建立用例模型&…

ansible学习使用

1、ansible官网 官方文档 https://docs.ansible.com/ansible/latest/index.html ansible github页面 https://github.com/ansible/ansible 安装手册&#xff1a;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html 2、ansible架构简述 …

JavaScrpt_11 Web API 事件流、委托事件、其它事件、元素尺寸与位置

JavaScrpt_11 Web API 事件流、委托事件、其它事件、元素尺寸与位置 前言一、事件流1. 捕获和冒泡2. 阻止冒泡 二、委托事件三、其它事件1. 页面加载事件 2. 元素滚动事件 3. 页面尺寸事件 四、元素尺寸与位置 前言 进一步学习 事件进阶&#xff0c;实现更多交互的网页特效&…

手写CDN基本原理

本文已收录于专栏 《中间件合集》 目录 追本溯源概念说明需求分析核心功能代码实现A用户模块本地DNS模块CDN服务模块缓存服务模块原服务端 总结提升 追本溯源 CDN的发展源于对互联网内容传输速度和用户体验的需求。在互联网发展初期&#xff0c;内容的传输主要依赖于源服务器&a…

Unity/Shader 零碎知识点

坐标系 Unity使用的是左手坐标系&#xff1b;观察空间&#xff0c;通俗来讲就是以摄像机为原点的坐标系&#xff0c;摄像机的前向是z轴的负方向&#xff0c;与模型和世界空间中的定义相反&#xff0c;z轴的坐标减少意味着场景深度的增加 点积 abba|a||b|cos<a,b> 结果为常…