前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >判断是不是平衡二叉树

判断是不是平衡二叉树

作者头像
秦怀杂货店
发布于 2022-02-17 00:36:40
发布于 2022-02-17 00:36:40
1.1K00
代码可运行
举报
文章被收录于专栏:技术杂货店技术杂货店
运行总次数:0
代码可运行

Part0前言

剑指Offer & LeetCode刷题仓库https://github.com/Damaer/CodeSolution 文档地址https://damaer.github.io/CodeSolution/ 刷题仓库介绍刷题仓库:CodeSolution 编程知识库https://github.com/Damaer/Coding 文档地址https://damaer.github.io/Coding/#/ 剑指OfferV1 系列已经完成,补增 V2 题目以及C++语言解法,欢迎关注~

倘若需要了解数据结构,可以点击:万字长文带你漫游数据结构世界

Part179.判断是不是平衡二叉树

1题目描述

输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树 平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

样例解释:

样例二叉树如图,为一颗平衡二叉树

注:我们约定空树是平衡二叉树。

  • 输入描述:输入一棵二叉树的根节点
  • 返回值描述:输出一个布尔类型的值

示例 1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: {1,2,3,4,5,6,7}

输出: true

示例 2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: {}

输出: true

2思路 & 解答

平衡树意味着我们需要对比任何在同一个根下的左右子树的高度差,还记得之前我们计算树的高度么,使用递归方式来解决,其实这道题与算高度差不多,只是两边高度需要算出一个差值。

算法的主要思想:

  • 不断对比每两个节点的左右子树的最大高度差,注意取差的绝对值,需要小于等于1
  • 对比完左右子树之后,需要递归左子树以及右子树进行分别判断,都满足才是平衡树

Java 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Solution79 {
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) return true;
        // 当前左右子树是否平衡以及左右子树分别是否平衡
        return Math.abs(depth(root.left) - depth(root.right)) <= 1 && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

    private int depth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // 递归获取深度
        return Math.max(depth(root.left), depth(root.right)) + 1;
    }
}

C++ 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    bool IsBalanced_Solution(TreeNode* root) {
        if (root == NULL) return true;
        // 当前左右子树是否平衡以及左右子树分别是否平衡
        return abs(depth(root->left) - depth(root->right)) <= 1
               && IsBalanced_Solution(root->left) && IsBalanced_Solution(root->right);
    }

    int depth(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        // 递归获取深度
        return max(depth(root->left), depth(root->right)) + 1;
    }
};
  • 时间复杂度 O(nlogn):最差情况下,需要遍历树所有节点判断是否平衡,需要O(n)。但是判断每个节点最大高度需要递归左右子树,需要占用 O(log2n),所以总共占用O(Nlog2n)
  • 空间复杂度O(n):最差情况下,也就是树退化为链表时,递归需要使用 O(n) 的栈空间,严格意义上递归栈也需要空间。

但是上面的计算,仔细观察就会发现会有很多重复计算的过程,比如下面的数,计算子树深度的时候,计算 1 的左子树,和计算 2 的,基本都重复了。

应该如何避免这种重复计算呢?前面的是自顶向下的方式,因为每个节点都得把子树计算一遍才需要重复,如果我们从下往上计算,那不就避免了重复计算,对比逻辑如下:

  • 如果当前节点为空,高度为0
  • 如果当前节点的左子树的高度为-1,那么说明不平衡,否则,需要计算右子树高度,同样需要不等于-1,如果两者的差不符合小于等于1,那么说明它们不平衡,返回-1。通过这样 -1 异常值就会一路返回,到最初的调用处,得到不平衡的结果。

Java 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Solution79 {
    public boolean IsBalanced_Solution(TreeNode root) {
        // 空树
        if (root == null) {
            return true;
        }
        return getHeight(root) != -1;
    }

    public int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // 左子树的高度
        int left = getHeight(root.left);
        if (left < 0) {
            return -1;
        }
        // 右子树的高度
        int right = getHeight(root.right);
        if (right < 0) {
            return -1;
        }
        return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
    }
}

C++ 代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    bool IsBalanced_Solution(TreeNode* root) {
        // 空树
        if (root == NULL) {
            return true;
        }
        return getHeight(root) != -1;
    }

    int getHeight(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        // 左子树的高度
        int left = getHeight(root->left);
        if (left < 0) {
            return -1;
        }
        // 右子树的高度
        int right = getHeight(root->right);
        if (right < 0) {
            return -1;
        }
        return abs(left - right) > 1 ? -1 : 1 + max(left, right);
    }
};
  • 时间复杂度O(n):每个节点计算一次
  • 空间复杂度O(n):递归需要使用额外堆栈空间

【作者简介】

秦怀,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人网站:http://aphysia.cn ,关注我,我们一起成长吧~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 秦怀杂货店 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
剑指Offer(三十九)-- 平衡二叉树
输入一棵二叉树,判断该二叉树是否是平衡二叉树。在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树 平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
秦怀杂货店
2022/02/15
3170
剑指Offer(三十九)-- 平衡二叉树
剑指Offer-平衡二叉树
package Tree; /** * 平衡二叉树 * 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 * 平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质: * 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 */ public class Solution20 { public static void main(String[] args) { Solution20
武培轩
2018/04/18
7370
[剑指offer] 平衡二叉树
遍历每个结点,借助一个获取树深度的递归函数,根据该结点的左右子树高度差判断是否平衡,然后递归地对左右子树进行判断。
尾尾部落
2018/09/04
2680
LeetCode-110. 平衡二叉树(java)
       根据本题对平衡二叉树的定义:如果二叉树的每个节点的左右子​​树的高度​​差的绝对值不超过 1,则是平衡二叉树。根据题目定义,解题思路如涌泉般喷发,老规矩,递归破题(若一棵二叉树是平衡二叉树,必须满足其所有子树也都是平衡二叉树才行),且递归的顺序可以是自顶向下或者自底向上,如上两种递归顺序我都给大家讲解一下。
bug菌
2023/05/27
2100
LeetCode-110. 平衡二叉树(java)
平衡二叉树判断_39
输入一棵二叉树,判断该二叉树是否是平衡二叉树。 在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树 平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
名字是乱打的
2021/12/23
2400
剑指offer | 面试题42:平衡二叉树
思路:平衡二叉树的条件:左子树是平衡二叉树,右子树是平衡二叉树,左右子树高度不超过 1。
千羽
2022/02/23
4100
剑指offer | 面试题42:平衡二叉树
二叉树——110. 平衡二叉树
树中的节点数在范围 [0, 5000] 内 -104 <= Node.val <= 104
向着百万年薪努力的小赵
2022/12/02
2630
二叉树——110. 平衡二叉树
平衡二叉树判断
平衡二叉树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
名字是乱打的
2022/05/13
1780
Leetcode No.110 平衡二叉树
示例 1: 输入:root = [3,9,20,null,null,15,7] 输出:true
week
2021/05/06
2650
二叉树精选面试题
判断结构相同:也就是在遍历的过程中,如果有一个节点为null,另一棵树的节点不为null,那么结构就不相同
2的n次方
2024/10/15
460
二叉树精选面试题
Leetcode 110. 平衡二叉树
二叉树为高度平衡二叉树,则二叉树中以任意节点为根节点的子树皆为高度平衡二叉树。仿照后序遍历二叉树每个节点,若左子树和右子树皆为高度平衡二叉树,则进一步判断左子树与右子树高度差是否大于一即可。
zhipingChen
2019/05/24
3830
平衡二叉树
完整高频题库仓库地址:https://github.com/hzfe/awesome-interview
HZFEStudio
2021/09/18
3890
LeetCode题解—二叉树
听名字还是比较好理解的,就是每个节点有两个分叉的树。但是又不要求一定有两个节点,只要小于等于2个节点就可以。
码上积木
2021/03/24
3730
二叉树刷题总结:二叉树的属性
这就需要去判断根节点下左子树与右子树里侧和外侧是否相等。比较的方法是拿左子树的 “左-右-中” 节点和右子树的“右-左-中”为顺序的节点做比较。
HelloWorld杰少
2022/08/04
3450
二叉树刷题总结:二叉树的属性
日拱算法之判断平衡二叉树
接上一篇《AVL 树旋转及 JS 实现,平衡树支棱起来~》,来了个难的,再来个相对简单的,别一直搁那“旋转树”而打击了“种二叉树”的自信心~~
掘金安东尼
2022/09/19
2180
LeetCode 训练场:110. 平衡二叉树
1. 题目 110. 平衡二叉树 2. 描述 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 3 / \ 9 20 / \ 15 7 返回 true 。 示例 2: 给定二叉树 [1,2,2,3,3,null,null,4,4] 1 / \ 2 2 / \ 3 3 /
村雨遥
2022/06/15
1610
leetcode 110-判断一棵树是否为平衡二叉树 #算法#
Given a binary tree, determine if it is height-balanced. 给出一棵二叉树,判断它是否高度平衡。 For this problem, a height-balanced binary tree is defined as: 高度平衡二叉树定义为:
梦飞
2022/06/23
1960
二叉树基础及实现(二,加经典OJ)
一 .接引二叉树(一):承接上篇,不清楚的可以回去看看:二叉树基础及实现(一)-CSDN博客 1. 判断一棵树是不是完全二叉树: 图解: 把二叉树元素放入队列中,如果最后队列里全部是元素,“null”,则该二叉树就是完全二叉树。 这里注意区分,空和元素,“null”的概念
用户11305962
2024/10/09
820
二叉树基础及实现(二,加经典OJ)
golang刷leetcode 技巧(21)平衡二叉树
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
golangLeetcode
2022/08/02
1950
C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址:  http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=
Enjoy233
2019/03/05
5680
相关推荐
剑指Offer(三十九)-- 平衡二叉树
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文