@Leetcode平衡二叉树
树类型的典型题之一,废话少说,直接来题干:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]返回true。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]返回false。
题干并不复杂,甚至大家一眼就可以看出true和false的区别:树的左右子树的高度明显不同。但是本题绕了个小弯,这需要你十分清楚平衡二叉树的定义,才能一眼发现解题的破绽。笔者很菜,花了不少时间才发现了这个问题,并且还在如何判断每个子结点的子树高度上“红橙做伴”了许久才得出一份潦草的代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(root==NULL)
return true;
else if(root->left||root->right){
if(judgeHeight(root)>=0)
return true;
else
return false;
}
return true;
}
int judgeHeight(TreeNode* root){
if(!root)
return 0;
int leftnum=judgeHeight(root->left);
if(leftnum<0)
return leftnum;
int rightnum=judgeHeight(root->right);
if(rightnum<0)
return rightnum;
if(abs(leftnum-rightnum)<2)
return max(leftnum,rightnum)+1;
else
return -1;
}
};
相信每位code都有尝试各种不同的递归思路,笔者也不例外,现在看到这的你,是否也出现了下面TLE的问题:
如果你也遇到了这个问题,那么很可能你的递归判断是分了左右子树分别判断高度并最终返回其中最高的数值再在主函数中进行比较,不得不说,这个方法,确实会超出时间限制,笔者亲测不成功,请大家另辟蹊径。
那么笔者通过的思路是什么呢?仍然是递归,只不过这一次直接返回了整棵树是否满足要求,避免了很多的二次判断,即使如此笔者还是在主函数中加上了一些基础的判断以解决空树和树中只有一个根结点这两种特殊情况。
具体的思路在judgeHeight这个函数里面,只需比较左子树高度和右子树高度差值的绝对值是否超过2,只要不超过,高度便可定为两者较大值加1(本层满足),否则返回-1。这个-1的返回要一层层往上往上往上返回(由中间的两个if判断一层层返回),最终返回到主函数中结束判断并输出false。
值得一提的是主函数最后的return true是必须加上的,而且只能写true,原因很简单,在主函数中唯一没有用if表示的可能状态就是只有一个根结点的情况,而这种情况下的树显然是一个平衡二叉树,故必须返回true,而且这里不能写else if,因为整个函数必须要有返回值,如果所有的return都在if之中,代码是不能通过的,系统会在你的主函数的最后一个括号处报错。