平衡二叉树
第三十八题:平衡二叉树
题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
概念:
它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过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);
}
}