题目要求
给定一个二叉树,判断它是否是平衡二叉树
平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。
提示:
- 树中的节点数在范围
[0, 5000]
内 -104 <= Node.val <= 104
解题思路
可以参考前面LeetCode104.二叉树的最大深度的思路来进行解题。
重要性质:当前节点的深度为左子树深度和右子树深度之间的最大值+1。
为什么我自己想的时候解不了题呢?因为没有确实理解104中,递归函数所返回的值是当前节点的深度。所以说对递归的性质还是不太熟悉。说明在某些递归中,当前层的返回值就是子问题的最终解。
先序遍历+判断深度(从顶向下)
思路:可以构造一个函数来判断当前树的左子树和右子树深度差是否大于1:abs(depth(root.left) - depth(root.right)) <= 1,从而判断当前树是否为平衡二叉树,如果是的话,进行先序遍历,先遍历左子树,再遍历右子树。如果所有子树都是平衡二叉树,那么这棵树就是平衡二叉树。
算法步骤
这里我们有两个函数。
函数isBalanceRoot(TreeNode root):判断树是否平衡
- 特殊处理:如果root为空,则返回true
- 返回值:判断左子树是不是平衡二叉树,判断右子树是不是平衡二叉树,判断当前root是不是平衡二叉树
abs(self.depth(root.left) - self.depth(root.right)) <= 1
:判断 当前子树 是否是平衡树。self.isBalanced(root.left)
: 先序遍历递归,判断 当前子树的左子树 是否是平衡树。self.isBalanced(root.right)
: 先序遍历递归,判断 当前子树的右子树 是否是平衡树。
这里的2,3步是必要的,我当时在想,是否在这个节点里,他是平衡二叉树,但是他的左右子节点并不是。所以我试了一下,确实会出现这种情况。
函数 depth(root) : 计算树 root 的深度
终止条件: 当 root 为空,即越过叶子节点,则返回高度 0 。
返回值: 返回左 / 右子树的深度的最大值 +1 。
代码解析
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null){
return true;
}
//先序遍历
//只有当三个条件都满足时,这个root为根节点的树才是平衡二叉树
boolean result1 = Math.abs(maxDepth(root.left)-maxDepth(root.right)) <= 1;
boolean result2 = isBalanced(root.left);
boolean result3 = isBalanced(root.right);
return result1 && result2 && result3;
}
//来自于104 计算当前root为根节点的树的最大深度
public int maxDepth(TreeNode root){
if(root == null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left,right) + 1;
}
}