代码随想录二刷 | 二叉树 | 110.平衡二叉树

news2024/12/23 23:09:10

代码随想录二刷 | 二叉树 | 110.平衡二叉树

  • 题目描述
  • 解题思路
    • 递归
    • 迭代
  • 代码实现
    • 递归法
    • 迭代法

题目描述

110.平衡二叉树

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

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

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

示例 1:
在这里插入图片描述
输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:
在这里插入图片描述
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

输入:root = []
输出:true

提示:

  • 树中的节点数在范围 [0, 5000] 内
  • -104 <= Node.val <= 104

解题思路

二叉树节点的高度:从根节点到该节点的最长简单路径边的条数

二叉树节点的深度:从该节点到叶子节点的最长简单路径变的条数

在这里插入图片描述
求深度可以从上到下去查询,所以需要前序遍历,而求高度只能从下到上去查,只能后序遍历。

因此本题使用后序遍历。

递归

递归三部曲

  1. 确定递归函数的参数和返回值
    参数:当前传入的节点
    返回值:因为求的是高度,所以为int

    如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。

    所以如果已经不是二叉平衡树了,可以返回 -1 来标记已经不符合平衡树的规则了。

    int getHeight(TreeNode* node)
    
  2. 确定终止条件
    遇到空节点时终止,返回0,表示当前节点为根节点的树高度为 0

    if (node == NULL) {
    	return 0;
    }
    
  3. 确定单层递归的逻辑
    分别求出左右子树的高度,如果差值小于等于 1 ,则返回当前二叉树的高度,否则返回 -1,表示已经不是平衡二叉树了。

    int leftHeight = getHeight(node->left);
    if (leftHeight == -1) return -1;
    int rightHeight = getHeight(ndoe->right);
    if (rightHeight == -1) return -1;
    int result;
    if (abs(leftHeight - rightHeight) > 1) {
    	result = -1;	
    } else {
    	result = 1 + max(leftHeight, rightHeight);
    }
    return result;
    

迭代

本题的迭代方式可以先定义一个函数,专门用来求高度。

这个函数通过栈模拟的后序遍历找每一个节点的高度(其实是通过求传入节点为根节点的最大深度来求的高度)

// cur节点的最大深度,就是cur的高度
int getDepth(TreeNode* cur) {
	stack<TreeNode*> st;
	if (cur != NULL) st.push(cur);
	int depth = 0; 
	int result = 0;
	while (!st.empty()) {
		TreeNode* node = st.top();
		if (node != NULL) {
			st.pop();
			st.push(node);
			st.push(NULL);
			depth++;
			if (node->right) st.push(node->right);
			if (node->left) st.push(node->left);
		} else {
			st.pop();
			node = st.top();
			st.pop();
			depth--;
		}
		result = result > depth ? result : depth;
	}
	return result;
}

然后再用栈来模拟后序遍历,遍历每一个节点的时候,再去判断左右孩子的高度是否符合,代码如下:

bool isBalanced(TreeNode* root) {
	stack<TreeNode*> st;
	if (root == NULL) return true;
	st.push(root);
	while (!st.empty()) {
		TreeNode* node = st.top();
		st.pop();
		if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {
			return fasle;
		}
		if (node->right) st.push(node->right);
		if (node->left) st.push(node->left);
	}
	return true;
}

当然此题用迭代法,其实效率很低,因为没有很好的模拟回溯的过程,所以迭代法有很多重复的计算。

虽然理论上所有的递归都可以用迭代来实现,但是有的场景难度可能比较大。

例如:都知道回溯法其实就是递归,但是很少人用迭代的方式去实现回溯算法!

因为对于回溯算法已经是非常复杂的递归了,如果再用迭代的话,就是自己给自己找麻烦,效率也并不一定高。

代码实现

递归法

class Solution {
public:
	int getHeight(TreeNode* node) {
		if (node == NULL) return 0;
		int leftHeight = getHeight(node->left);
		if (leftHeight == -1) return -1;
		int rightHeight = getHeight(node->right);
		if (rightHeight == -1) return -1;
		return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftheight, rightHeight);
	}
    bool isBalanced(TreeNode* root) {
        return getHeight(root) == -1 ? false : true;
    }
};

迭代法

class Solution {
public:
class Solution {
private:
    int getDepth(TreeNode* cur) {
        stack<TreeNode*> st;
        if (cur != NULL) st.push(cur);
        int depth = 0; // 记录深度
        int result = 0;
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop();
                st.push(node);                          // 中
                st.push(NULL);
                depth++;
                if (node->right) st.push(node->right);  // 右
                if (node->left) st.push(node->left);    // 左

            } else {
                st.pop();
                node = st.top();
                st.pop();
                depth--;
            }
            result = result > depth ? result : depth;
        }
        return result;
    }

public:
    bool isBalanced(TreeNode* root) {
        stack<TreeNode*> st;
        if (root == NULL) return true;
        st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top(); 
            st.pop();
            if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {
                return false;
            }
            if (node->right) st.push(node->right);           // 右(空节点不入栈)
            if (node->left) st.push(node->left);             // 左(空节点不入栈)
        }
        return true;
    }
};

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

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

相关文章

首发卡密引流系统源码

程序特色&#xff1a; 支持个人和企业小程序广告获取卡密。 支持短视频点赞和关注获取卡密。 搭建教程&#xff1a; 环境要求&#xff1a;Nginx、MySQL 5.6、PHP 5.6 步骤&#xff1a; 将压缩包解压至网站根目录。 打开域名/install&#xff0c;按照提示填写数据库信息进行…

【Android】使用 Glide 给 ImageView 加载图像的简单案例

前言 Android Glide是一个用于在Android应用中加载和显示图片的流行开源库。它提供了简单易用的API&#xff0c;可以帮助开发者高效地加载远程图片、本地图片以及GIF动画&#xff0c;并提供了缓存、内存管理等功能&#xff0c;使得图片加载在移动应用中更加流畅和高效。Glide还…

智慧健康监测设备行业分析:中国市场发展潜力巨大

中国智慧健康行业市场规模呈逐年快速增长态势&#xff0c;年均复合增长率超过40%。其中智能可穿戴设备出货量巨大。国务院办公厅印发《“十四五”国民健康规划》。规划提出&#xff0c;促进健康与养老、旅游、互联网、健身休闲、食品等产业融合发展&#xff0c;壮大健康新业态、…

谁能更好地检测深度伪造?人还是机器?

不知您是否听说过深度伪造&#xff08;Deepfakes&#xff09;这种欺诈应用&#xff1f;由它产生的各种虚假信息已威胁到了人类社会的方方面面。随着人工智能技术的进步&#xff0c;我们亟待提升识别虚假内容的能力。那么在实际检测假新闻可信度等用例时&#xff0c;到底是人类还…

营销投放下半场,游戏行业如何寻觅进化空间?

摘要&#xff1a;微博&#xff0c;游戏行业突围市场新利器 游戏行业&#xff0c;格局永远在变。 从2017年互联网大厂集体盯上游戏大蛋糕&#xff0c;到2021年行业收缩&#xff0c;再到今年上半年实际销售收入继去年首次出现同比下滑…几经过山车式行情的游戏行业&#xff0c;…

Vue3上传图片和删除图片

<div class"illness-img"><van-uploader:after-read"onAfterRead"delete"onDeleteImg"v-model"fileList"max-count"9":max-size"5 * 1024 * 1024"upload-icon"photo-o"upload-text"上传图…

Attention机制学习

写在前面 注意力机制是一个很不错的科研创新点方向&#xff0c;但是没有系统记录过学习过程&#xff0c;这里记录科研中遇到的各种注意力机制。 Attention机制解释 本质上来说用到attention的任务都有Query&#xff0c;Key&#xff0c;Value三个关键components&#xff0c;目标…

LeetCode 300最长递增子序列 674最长连续递增序列 718最长重复子数组 | 代码随想录25期训练营day52

动态规划算法10 LeetCode 300 最长递增子序列 2023.12.15 题目链接代码随想录讲解[链接] int lengthOfLIS(vector<int>& nums) {//创建变量result存储最终答案,设默认值为1int result 1;//1确定dp数组&#xff0c;dp[i]表示以nums[i]为结尾的子数组的最长长度ve…

“文思助手”苏哒智能加入飞桨技术伙伴计划,共同打造“大模型+企业办公”新模式

近日&#xff0c;厦门苏哒智能科技有限公司正式加入飞桨技术伙伴计划&#xff0c;双方将发挥各自的专业优势&#xff0c;共同致力于在智能办公和创作领域实现技术突破和业务创新&#xff0c;帮助企业、知识工作者大幅提高生产力。 厦门苏哒智能科技有限公司 厦门苏哒智能科技有…

前端自定义icon的方法(Vue项目)

第一步&#xff1a;进入在线的编辑器进行设计 好用&#xff1a;百度字体编辑器 比如先导入有个ttf文件 添加新字体 双击每个模块进入编辑区域 更改相应的信息&#xff0c;比如name 编辑完了进行导出文件(各种格式就行了)就行了 第二步&#xff1a;在项目中asset文件储存这些文…

TCP为什么可靠之“拥塞控制”

拥塞控制是对网络层面的控制&#xff0c;主要是为了避免发送方发送过多的数据导致网络阻塞&#xff0c;以及出现网络阻塞时能够调整数据发送速率&#xff0c;达到对网络阻塞的一个控制。 拥塞窗口 拥塞窗口cwnd&#xff0c;是发送方维护的一个状态变量&#xff0c;会根据网络…

Vue组件封装知识总结

一、为什么要封装组件 首先&#xff0c;一个好问题&#xff0c;面试要考的&#xff01;为什么要封装组件呢&#xff1f; 提高代码的复用性&#xff1a;通过封装&#xff0c;可以将一段代码或一部分功能抽象为一个独立的组件&#xff0c;并在不同的项目或场景中重复使用。这样可…

simulinkveristand联合仿真——模型导入部署简单人机界面

目录 软件版本 simulink模型编译 veristand导入模型 veristand模型参数设置 veristand配置人机交互界面 veristand模型部署运行 软件版本 matlab2020a&#xff0c;veristand2020 R4 环境搭建及软件获取可看simulink&veristand&labview联合仿真环境搭建-CSDN博客…

记录 | docker报错could not select device driver ““ with capabilities: [[gpu]].

ubuntu18.04 上启动 docker start 报错&#xff1a; could not select device driver “” with capabilities: [[gpu]]. docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]]. ERRO[0005] error waiting for container: con…

如何做到人均告警减少 90%?B 站新一代告警平台的设计与实践

一分钟精华速览 B 站的业务规模和用户群体不断扩大&#xff0c;对于服务的稳定性和可用性的要求也日益增高。这就需要 B 站的监控告警系统能够及时、准确地发现和定位问题&#xff0c;以便尽快解决&#xff0c;维护好用户的使用体验。 本文是对 B 站在告警监控系统上的一次重…

MySQL如何进行Sql优化

&#xff08;1&#xff09;客户端发送一条查询语句到服务器&#xff1b; &#xff08;2&#xff09;服务器先查询缓存&#xff0c;如果命中缓存&#xff0c;则立即返回存储在缓存中的数据&#xff1b; &#xff08;3&#xff09;未命中缓存后&#xff0c;MySQL通过关键字将SQ…

网络层--TCP/UDP协议

目录 一、TCP/UDP协议介绍 1、UDP(User Datagram Protocol)--用户数据报协议 1.1 UDP报文格式 1.2 UDP协议的特性 2、TCP(Transmission Control Protocol )--传输控制协议 2.1 TCP报文格式 2.2 TCP协议的特性 2.3 TCP三次握手 2.4 四次挥手 三、TCP和UDP的区别 四、t…

关于“Python”的核心知识点整理大全21

9.3.2 Python 2.7 中的继承 在Python 2.7中&#xff0c;继承语法稍有不同&#xff0c;ElectricCar类的定义类似于下面这样&#xff1a; class Car(object):def __init__(self, make, model, year):--snip-- class ElectricCar(Car):def __init__(self, make, model, year):supe…

xcode 修改 target 中设备朝向崩溃

修改xcode的target中的设备朝向导致崩溃。 从日志上看好像没有什么特别的信息。 之后想了想&#xff0c;感觉这个应该还是跟xcode的配置有关系&#xff0c;不过改动的地方好像也只有plist。 就又翻腾了半天plist中的各种配置项&#xff0c;再把所有的用户权限提示相关的东西之…

运筹学经典问题(三):最大流问题

问题描述 给定一个图网络 G ( V , E ) G(V, E) G(V,E)&#xff0c;网络中连边的权重代表最大容量&#xff0c;在这个图中找出从起点到终点流量最大的路径。 数学建模 集合&#xff1a; I I I&#xff1a;点的集合&#xff1b; E E E&#xff1a;边的集合。 常量&#x…