Lecode110:平衡二叉树
方法1:自底向上递归
思路:
dfs问题涉及的类型包括是返回所有路径,但是可能有限定条件;或者是对每个结点遍历判断赋值并返回。dfs多用return,bfs多用continue。这道题目属于第二种方法,但是这里又涉及到返限定条件:左右子树的高度绝对值不超过1。
这意味着我们需要在程序中对每个结点进行判断高度,那就涉及到对每个节点要返回高度记录值,但是该程序最终需要返回是非的结果,所以第一想法是不能直接对原函数做递归,而是通过一个额外的递归函数来返回一个高度值,通过高度值来判断是或非。在这里我设置一旦左右子树出现问题,那么就赋值-1.接下来就不进行后续的高度计算和判断了 ,全部返回负1.即这种思路是从下往上递归判断到顶点
刚开始写程序可能会搞不清左子树还是当前子树层数的问题,其实既然是递归就选择某一层来看返回结果即可,这里可以选最后一次return0的特例来分析,下面的程序返回的是计算当前层后的结果 0+0+1; 即程序返回的高度是当前在某一层时候的高度,然后返回,返回时进入left所以是子树高度。子是针对left right 和当前层而言
class Solution {
public:
bool isBalanced(TreeNode* root) {
//深度优先遍历
if(!root)
return true;
return bfs(root)>0;
}
int bfs(TreeNode* root){
if(!root)
return 0;
int left=bfs(root->left);
int right=bfs(root->right);
if(left==-1 || right==-1)
return-1;
if(abs(left-right)>1)
return -1;
return max(left,right)+1;
}
};
对上面代码做一个简单优化处理:
if (leftHeight == -1 || rightHeight == -1 || abs(leftHeight - rightHeight) > 1) {
return -1;
} else {
return max(leftHeight, rightHeight) + 1;
}
方法2:自顶向下递归
思路: 根据定义,一棵二叉树是平衡二叉树,当且仅当其所有子树也都是平衡二叉树,因此可以使用递归的方式自顶向下来判断,对每个结点先判断左右子树是否符合差值小于等于1的条件,然后再从上到下继续遍历每个节点,判断每个节点是否都符合平衡二叉树的条件。下面代码中height用来计算高度,isBalanced用来对节点扩张~递归调用。
class Solution {
public:
int height(TreeNode* root) {
if (root == NULL) {
return 0;
} else {
return max(height(root->left), height(root->right)) + 1;
}
}
bool isBalanced(TreeNode* root) {
if (root == NULL) {
return true;
} else {
return abs(height(root->left) - height(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
}
};