剑指OFFER题12------按牛客网通过率排序
时间:2018.10.21.1959
作者:Waitt
题目
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
时间限制:1秒 空间限制:32768K 热度指数:140302
解答
平衡二叉树
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
PS:平衡二叉树未必是二叉排序树,比如二路堆就可以实现为平衡二叉树,且非二叉排序树
PS:只有在用平衡二叉树进行查找或者排序的时候才是二叉排序树
思路1
遍历每个结点,借助一个获取树深度的递归函数,根据该结点的左右子树高度差判断是否平衡,然后递归地对左右子树进行判断。
但是这种做法虽然很简单,但在判断上层结点的时候,会多次重复遍历下层结点,增加了不必要的开销。
class Solution {
public:
int Dep(TreeNode* pRoot)
{
if (pRoot==NULL)
return 0;
int l=Dep(pRoot->left)+1;
int r=Dep(pRoot->right)+1;
return max(l,r);
}
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==NULL)
return 1;
return ((abs(Dep(pRoot->left)-Dep(pRoot->right))<=1)&&
IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right));
}
};
思路2
如果改为从下往上遍历,如果子树是平衡二叉树,则返回子树的高度;如果发现子树不是平衡二叉树,则直接停止遍历,这样至多只对每个结点访问一次。
class Solution {
public:
int Dep(TreeNode* pRoot)
{
if (pRoot==NULL)
return 0;
int l=Dep(pRoot->left);
if(l==-1)//此处的判断能够防止底层已经判断出的负数进入迭代计算
return -1;
int r=Dep(pRoot->right);
if(r==-1)//此处的判断能够防止底层已经判断出的负数进入迭代计算
return -1;
if(abs(l-r)>1)//此处用来判断树的平衡
return -1;
return max(l+1,r+1);//+1放在此处可防止-1的错误迭代计算
}
bool IsBalanced_Solution(TreeNode* pRoot) {
if (pRoot==NULL)
return 1;
return (Dep(pRoot)!=-1);
}
};
小知识点
平衡二叉树是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的节点。
平衡二叉树未必是二叉排序树,比如二路堆就可以实现为平衡二叉树,且非二叉排序树,只有在用平衡二叉树进行查找或者排序的时候才是二叉排序树。