题目描述
我的解法
思路
先尝试用递归法解决
- 确定参数和返回值
返回值:true 或 false
参数:因为要比较每个节点两个子树的高度,所以参数是左节点和右节点 - 确定终止条件
- 如果左右节点都为空 返回ture
- 如果左、右节点只有一个为空,则判断另一个节点的左右子节点是都为空,若存在不为空的,返回false,否则返回treu
- 确定单层的操作逻辑
将当前节点的左右子节输入递归函数进行判断
尝试完发现上面的思路存在问题
上面的做法只能看到当前访问节点的左右节点下一层的情况,判断左右节点高度差小于等于1就下移了,但是平衡树判断应该考虑整体的情况,当前节点的高度差是1,但是下一层节点可能还会有1的高度差,这样就是2了
修改后的
所以需要获取全局的信息,递归函数的作用是统计节点的高度
那么过程中如何标记左右子树是否差值大于1呢?如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。
- 确定参数和返回值
返回值:如果不是二叉平衡树返回-1,如果是返回高度
参数:节点指针 - 确定终止条件
如果当前访问节点为null,则返回0 - 明确单层递归的逻辑
如果判断当前传入节点为根节点的二叉树是否是平衡二叉树呢,判断左子树高度和右子树高度差。
分别求出左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则则返回-1,表示已经不是二叉树了。
对应Java代码
class Solution {
public boolean isBalanced(TreeNode root) {
return getDepth(root) == -1 ? false : true;
}
public int getDepth(TreeNode cur){
if(cur == null) {return 0;}
int leftDepth = getDepth(cur.left);
if(leftDepth == -1){return -1;}
int rightDepth = getDepth(cur.right);
if(rightDepth == -1){return -1;}
return Math.abs(leftDepth - rightDepth) > 1 ? -1 : 1 + Math.max(leftDepth,rightDepth);
}
}
复杂度分析
时间复杂度:O(n) 其中n是二叉树中的节点个数,使用自底向上的递归,每个节点的计算高度和判断是否平衡都只需要处理一次。
空间复杂度:O(n) 其中n 是二叉树中的节点个数。空间复杂度主要取决于递归调用的层数,递归调用的层数不会过n。
迭代法思路
需要先编写一个求当前访问节点高度的函数,然后在正常节点的遍历过程中反复调用,有很多重复的计算,时间复杂度是O(n²) 虽然理论上所有的递归都可以用迭代来实现,但是有的场景难度可能比较大,比如都知道回溯法其实就是递归,但是很少人用迭代的方法区实现回溯算法