1.题目
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
题目链接
2.解题分析
2.1常规解法
分别求出左右子树的高度,再判断左右子树的高度差是否超过1
实现代码
int Hight(struct TreeNode *root)
{
if(root==NULL)
return 0;
//求该节点的左右子树高度
int left=Hight(root->left)+1;
int right=Hight(root->right)+1;
//左右子树中高度最高的即为该节点的高度
return left>right?left:right;
}
bool isBalanced(struct TreeNode* root){
if(root==NULL)
return true;
int left=Hight(root->left);//左子树高度
int right=Hight(root->right);//右子树高度
return
(abs(left-right)<2)&&
isBalanced(root->left)&&
isBalanced(root->right);//遍历判断每个节点的左右子树的高度差
}
时间复杂度分析:
上述代码,是通过遍历每一个节点来判断是否符合条件,要是不符合条件的情况位于倒数的节点位置,那么时间复杂度会非常的高,达到了O(N^2);
2.2优化解法
由上述的前序遍历的方法我们知道,时间复杂度达到了O(N^2),那么怎么进行优化呢?
我们可以通过后序遍历的方法,即利用前面计算出来的高度来判断是否满足平衡二叉树的条件,而不是单独计算每一个节点的左右子树的高度;
实现代码
bool _isBalanced(struct TreeNode *root,int *depth)
{
if(root==NULL)
{
*depth=0;
return true;
}
int LetfDepth=0;
if(_isBalanced(root->left,&LetfDepth)==false)//左子树
return false;//如果不满足平衡条件则直接返回
int RightDepth=0;
if(_isBalanced(root->right,&RightDepth)==false)//右子树
return false;
if (abs(LetfDepth-RightDepth)>1)//判断当前节点是否满足条件
return false;
*depth=LetfDepth>RightDepth?LetfDepth+1:RightDepth+1;//当前节点的高度
return true;
}
bool isBalanced(struct TreeNode* root){
int depth=0;
return _isBalanced(root,&depth);
}
时间复杂度分析:
采用后续的遍历方式,如果当前节点满足要求返回true,并且带上了当前节点的高度,因此返回上一层的时候不需要再次计算节点高度,因此时间复杂度为O(N);