1 题目描述
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
示例1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回true。
示例2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回false。
限制:
1 <= 树的结点个数 <= 10000
2 解题思路
2.1 方法1:后序遍历+剪枝(从底至顶)(最优解法)
思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。
算法流程:
recur(root)
函数:
- 返回值:
- 当节点root左/右子树的深度差小于等于1:则返回当前子树的深度,即节点root的左/右子树的深度最大值+1(max(left,right)+1);
- 当节点root左/右子树的深度差大于2;则返回-1,代表此子树不是平衡树。
- 终止条件:
- 当root为空:说明越过叶节点,因此返回高度0;
- 当左(右)子树深度-1:代表此树的左(右)子树不是平衡树,因此剪枝,直接返回-1;
isBalanced(root)
函数:
- 返回值:若recur(root)!=-1,则说明此树平衡,返回true;否则返回false。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
return recur(root) == -1 ? false : true;
}
private int recur(TreeNode node) {
if (node == null) return 0;
int left = recur(node.left);
if (left == -1) return -1;
int right = recur(node.right);
if (right == -1) return -1;
return Math.abs(left - right) < 2 ? Math.max(left,right) + 1 : -1;
}
}
复杂度分析:
- 时间复杂度O(N):N为树的节点数;最差情况下,需要递归遍历树的所有节点。
- 空间复杂度O(N):最差情况下(树退化为链表时),系统递归需要使用O(N)的栈空间。
2.2 方法2:先序遍历 + 判断深度 (从顶至底)
思路是构造一个获取当前子树的深度的函数depth(root),通过比较某子树的左右子树的深度差abs(depth(root.left)-depth(root.right)) <= 1是否成立,来判断某子树是否是二叉平衡树。若所有子树都是平衡,则此树平衡。
算法流程:
isBalanced(root)
函数:判断树root是否平衡
- 特例处理:若树根节点root为空,则直接返回true;
- 返回值:所有子树都需要满足平衡树性质,因此以下三者使用与逻辑&&连接;
- abs(depth(root.left)-depth(root.right))<=1:判断当前子树是否为平衡树;
- isBalanced(root.left):先序遍历递归,判断当前子树的左子树是否平衡树;
- isBalanced(root.right):先序遍历递归,判断当前子树的右子树是否为平衡树;
wei
depth(root)
函数:计算树root的深度。
- 终止条件:当root为空,即越过叶子节点,则返回高度0;
- 返回值:返回左/右子树的深度的最大值+1。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int depth(TreeNode node) {
if (node == null) return 0;
return Math.max(depth(node.left),depth(node.right)) + 1;
}
}
复杂度分析:
时间复杂度O(NlogN):最差情况下(为“满二叉树”时),isBalanced(root)遍历树所有节点,判断每个节点的深度depth(root)需要遍历各子树的所有节点。
- 空间复杂度O(N):最差情况下(树退化为链表时),系统递归需要使用O(N)的栈空间。