题目描述:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
分析:
平衡二叉树的定义就是要求每个节点的左右两棵子树的高度差的绝对值不超过1,所以问题的关键就是需要求出每个节点的高度差,然后判断。
思路一:
考虑的关键:!!!
一开始我思考能不能直接通过一个递归函数就把每一个节点的高度差计算出来,但是通过实践以及思考,发现:计算高度差必须先求出左右子树的高度,然后做差!如果直接将递归函数返回高度差,上一层的节点就没有办法计算高度差了(因为计算高度差必须知道左右子树的高度,而方法的返回值是高度差!!!)
具体解释过程如下图所示:
方法一的关键点:
高度差
:通过上面的分析,因此我采用定义一个类的成员变量(int num=0)来记录二叉树中所有节点中的最大高度差。递归方法( getHeightValue())
:返回值为每个节点的高度,目的是为了在每次递归中能求每个节点的高度差,高度差变量(num)就镶嵌在递归方法中。isBalanced()方法
:只需要判断高度差是否满足条件。
代码实现:
class Solution {
//num表示整个树中所有节点的最大高度差
public int num=0;
//通过递归遍历每个节点的高度差,得到最大的
public int getHeightValue(TreeNode root)
{
if(root==null) { return 0; }
//求左右子树的高度,然后做差
int leftHeight=getHeightValue(root.left);
int rightHeight=getHeightValue(root.right);
if(num < Math.abs(leftHeight-rightHeight))
{
num=Math.abs(leftHeight-rightHeight);
}
//返回值还是返回该节点为根的高度(即:左右子树的最大高度)
return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
}
public boolean isBalanced(TreeNode root) {
if(root==null ){return true;}
getHeightValue(root);
if(num > 1 || num<0){return false;}
return true;
}
}
运行结果:
注意:
我在一开始将num定义为static,然后代码就不能通过,还出现了这样的问题,见下图:
当时我很诧异,还以为是leetcode出现问题了,然后刷新一直还是这样!!
通过一段时间的挣扎,总算明白为什么会是这样!!
原因:
- 静态变量(num)在实例方法getHeightValue()中每次被改变,不同的对象使用它就会使用的是上一个对象改变的静态变量(num)。
- 在点击“执行代码”按钮的时候,只跑一个测试用例,当然也只生成一个实例对象,所以如上图所示结果是对的!
- 点击“提交”按钮,leetcode会将后台所有的测试用例都跑一遍,又因为我的代码是实例方法,所以前面的对象改变了静态变量(num)的值后,后面测试用例的对象在使用静态变量(num)时,其实使用的是上一个对象改变后的num值。因此出现上图的结果是错的!
思路二:
这种方法是参考大佬的!效率大大提升,在一定程度上减少了栈帧的开辟(递归)! 一块来学习一下。
方法:
getHeightValue()
:递归求二叉树中每个节点的高度isBalanced()
:主要是来判断高度差的。- root=null:返回true
- 如果根节点的左右高度差大于1:直接返回false;此处就是减少递归的关键所在!!减少了内存的开辟提高了效率。(因为根节点的高度差不满足平衡二叉树的要求就没有必要考虑其他子节点了。)
- 根节点的左右高度差小于1:继续判断其他节点的高度差
class Solution {
//求二叉树中每个节点的高度
public int getHeightValue(TreeNode root)
{
if(root==null)
{
return 0;
}
//分别求该节点左右子树的高度
int leftHeight=getHeightValue(root.left);
int rightHeight=getHeightValue(root.right);
return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
}
public boolean isBalanced(TreeNode root) {
if(root==null)
{
return true;
}
//如果根节点的左右高度差不小于1,直接返回false
if(Math.abs(getHeightValue(root.right)-getHeightValue(root.left))>1)
{
return false;
}
//如果根节点的左右高度差小于1,那麽继续判断其他节点的高度差
return isBalanced(root.left) && isBalanced(root.right);
}
}
运行结果:
两种方法对比: