Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
分析:要求1:一个树不能出现一边子树为空,另一边子树高度大于1;
2:左右子树都是平衡二叉树。
在第一次提交的时候做的代码如下:
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int lh=0;
int rh=0;
lh = maxDepth(root.left);
rh = maxDepth(root.right);
if(lh>=rh){
return lh+1;
}
else{
return rh+1;
}
}
/*平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树*/
public boolean isBalanced(TreeNode root) {
if(root == null){
return true;
} else{
if(root.left == null && root.right == null){
return true;
}
if(root.left == null && (root.right.left!=null || root.right.right!=null)){
return false;
}
if(root.right == null && (root.left.left!=null || root.left.right!=null)){
return false;
}
}
int differ = maxDepth(root.left) - maxDepth(root.right);
return isBalanced(root.left) && isBalanced(root.right) && (differ == 1 || differ==0 || differ==-1);
}
之后想了想,发现可以简化上述代码。纯计算一个树的左右子树的高度差来决定。需要注意的是需要判断给定树的每个节点的左右子树高度差不大于1.
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int lh=0;
int rh=0;
lh = maxDepth(root.left);
rh = maxDepth(root.right);
if(lh>=rh){
return lh+1;
}
else{
return rh+1;
}
}
public boolean isBalanced(TreeNode root) {
if(root == null){
return true;
}
int differ = maxDepth(root.left) - maxDepth(root.right);
if(differ == 1 || differ==0 || differ==-1){
return isBalanced(root.left) && isBalanced(root.right);
}
return false;
}
上述方法的好处是代码规整,利于理解,但是会重复计算以某个结点为根的子二叉树的深度。
所以提出了下面的解法(具体可见剑指offer第210页)
/**
* 根据用递归算法解决平衡二叉树时会重复计算子二叉树的深度,所以提出下面的解决方法。
* 在计算以某个结点为根结点的二叉树是否为平衡二叉树时,记录下当前子二叉树的深度,便于后面直接使用。
* 采用的是二叉树的后序遍历方法,每次都记录下孩子结点的高度。
*/
public boolean IsBalanced_Solution2(TreeNode root) {
int[] depth = {0};
return IsBalanced(root,depth);
}
/**
*
* @param root
* @param depth 这个root结点在二叉树中的深度.
* @return
*/
public boolean IsBalanced(TreeNode root,int[] depth){
if(root == null){
return true;
}
/*分别存以左孩子和右孩子为根结点时的二叉树的深度*/
int[] left = {0};
int[] right = {0};
if(IsBalanced(root.left,left) && IsBalanced(root.right,right)){
int diff = left[0] - right[0];
if(diff == 1 || diff==0 || diff==-1){
depth[0] = 1+(left[0]>right[0]?left[0]:right[0]);
return true;
}
}
return false;
}