# 剑指 Offer 55 - II. 平衡二叉树
大家好,我是吴师兄。
今天继续来学习《剑指Offer》系列的一道经典题目,依旧给出了非常详细的题解和精美的配图与动画。
# 一、题目描述
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
# 二、题目解析
判断一棵树是否是平衡树,首先第一步是要去获取它的左右子树的高度。
在获取高度的过程中,如果出现了某个节点的左右子树的高度差超过了 1 ,那也就意味着这个节点组成的子树不是平衡二叉树,更进一步,含有这个子树的二叉树也不是平衡二叉树。
因此,本题的操作如下:
1、自底向上判断,只要发现有叶子树出现非平衡二叉树的情况,那么就是不是平衡二叉树了
2、递归的去计算当前节点的左子树高度,如果发现左子树是非平衡二叉树,直接返回这个结果而无需再去获取右子树的高度。
3、否则,递归的去计算当前节点的右子树高度,如果发现右子树是非平衡二叉树,直接返回这个结果而无需再去计算左右子树的高度差是多少。
4、否则计算一下当前节点 curNode 是否是平衡二叉树,即计算左右子树的高度差是否为 1。
5、再将如上的结果返回给它们的父节点,直到找到结果或者来到根节点为止。
为了帮助你更好的理解整个过程,我特意做了一组动画,点开可以查看:
# 三、参考代码
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 平衡二叉树( LeetCode 110 ):https://leetcode-cn.com/problems/balanced-binary-tree
class Solution {
public boolean isBalanced(TreeNode root) {
// 自底向上判断,只要发现有叶子树出现非平衡二叉树的情况,那么就是不是平衡二叉树了
return recur(root) != -1;
}
private int recur(TreeNode curNode) {
// 递归终止条件
// 如果当前节点 curNode 为空,那么高度就是 0
if (curNode == null) return 0;
// 递归的计算当前节点 curNode 的左子树高度
int left = recur(curNode.left);
// 如果发现为 -1,即表示左子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
// 提前终止了后续的判断
if(left == -1) return -1;
// 递归的计算当前节点 curNode 的右子树高度
int right = recur(curNode.right);
// 如果发现为 -1,即表示右子树中出现了高度差大于 2 的情况,已经不是平衡二叉树了,可以直接返回这个结果给上层
// 提前终止了后续的判断
if(right == -1) return -1;
// 1、否则说明在 curNode 的左子树中没有发现不是平衡二叉树的情况
// 2、否则说明在 curNode 的右子树中没有发现不是平衡二叉树的情况
// 因此计算一下当前节点 curNode 是否是平衡二叉树
// 即计算 curNode 的左子树高度与右子树高度差
// 如果发现小于 2,那么返回以当前节点 curNode 为根节点的子树的最大高度
// 即节点 curNode 的左右子树中最大高度加 1
return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
}
}