一.题目描述
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
提示:
树中的节点数在范围 [0, 5000] 内
-104 <= Node.val <= 104
二.题目解析
public boolean isBalanced(TreeNode root) {
/*根据二叉平衡树定义
"一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1"
自顶向下判断
时间复杂度O(nlogn),最差情况下遍历n个节点,对每个节点调用calculateHeight函数是logn的时间
空间复杂度O(n),最差情况下,递归需要O(n)的栈空间
* */
if(root == null){
return true;
}
//分别计算左子树和右子树的高度
int lHeight = calculateHeight(root.left);
int rHeight = calculateHeight(root.right);
//判断当前子树是否是平衡树,如果高度差绝对值大于1就不是高度平衡二叉树
if(Math.abs(rHeight - lHeight) > 1){
return false;
}
//判断当前子树的左子树/右子树是否是平衡树
return isBalanced(root.left) && isBalanced(root.right);
}
private int calculateHeight(TreeNode root){
/*递归,返回root节点的高度
时间复杂度O(nlogn)
* */
if(root == null){
return 0;
}
return Math.max(calculateHeight(root.left),calculateHeight(root.right)) + 1;
}
2.
public boolean isBalanced1(TreeNode root) {
/*思路是对二叉树做后序遍历,自底向上返回子树最大高度,
若某子树不是平衡树,直接向上返回-1。
时间O(n) N 为树的节点数;最差情况下,需要递归遍历树的所有节点
空间O(n) 最差情况下,递归需要O(n)的栈空间
* */
return height(root) != -1;
}
private int height(TreeNode root) {
/*自底向上很巧妙的既获取了高度又判断了是否平衡
平衡会返回root节点的高度,不平衡会返回-1
* */
if(root == null) {
return 0;
}
//“后序遍历”自底向上处理
int lh = height(root.left), rh = height(root.right);
//root.left为根节点的子树平衡&root.right为根节点的子树平衡&以root为根节点的子树平衡
if(lh != -1 && rh != -1 && Math.abs(lh - rh) <= 1) {
//返回root节点的高度,表示平衡
return Math.max(lh, rh) + 1;
} else {
//返回-1表示root节点作为根节点的子树不平衡,便开始层层向上返回-1
return -1;
}
}
注:
深度:对于任意节点n,n的深度为从根到n的唯一路径长,根的深度为0;
高度:对于任意节点n,n的高度为从n到一片树叶的最长路径长,所有树叶的高度为0(本题中按1处理);