平衡二叉树


题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。


概念:

它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
若将二叉树节点的平衡因子BF定义为该节点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有节点的平衡因子只可能为-1,0,1.
只要二叉树上有一个节点的平衡因子的绝对值大于1,那么这颗平衡二叉树就失去了平衡。


思路:

递归:

①判断每个节点是否是AVL树
②从root结点到叶子节点逐一进行判断
缺点:在计算每个节点的深度的时候,进行了多次的重复计算
这样计算的开销还是比较大的。


断每个节点是否是AVL树(代码实现):
// 判断每个节点是否是AVL树
public classSolution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) {
            return true;
        }
        // 如果满足高度差<=1 且 每颗子树也满足的条件话,才是AVL树
        return Math.abs(maxDepth(root.left) - maxDepth(root.right)) <= 1 &&
            IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
    // 计算树的深度
    private int maxDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}

判断结点的高度:

既然我们每次都要计算结点的高度,那么我们可以在计算高度的同时比较左右子树的高度差
这种思路是由从上往下的计算改为从下往上判断(只需要计算一遍高度差就能判断是否是AVL树)


具体实现如下图所示:

平衡二叉树


返例具体实现如下图所示:

平衡二叉树


具体实现代码如下:
// 从下往上判断深度差
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        // 不返回 -1 就说明左右子树中都符合AVL树的性质
        return getDepth(root) != -1;
    }
    // 计算树的深度,并判断左右子树的高度差
    private int getDepth(TreeNode root) {
        if (root == null)
            return 0;
        int left = getDepth(root.left);
        // 说明左子树的高度差超过了 1 ,此时不用去判断右子树,一路返回 -1
        if (left == -1)
            return -1;
        int right = getDepth(root.right);
        // 说明右子树的高度差超过了 1 ,一路返回 -1
        if (right == -1)
            return -1;
        // 判断左右结点的高度差是否超过 1
        return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
    }
}