题目: 给定一棵二叉树,判断是否是高度平衡的二叉树
概念简介:一棵高度平衡的二叉树是指一棵树的任一节点的左右两棵子树的高度差的绝对值不超过1。
示例:
1.2.
思路:
本题因能力有限,暂时考虑使用 暴力法 进行求解,即采用 从顶至下 的方法。
整体思路是刻画一个获取当前节点最大高度的方法depth(root),然后通过比较该子树的左右子树的最大高度差abs(depth(root.left) - depth(root.right)) 是否小于1来判断此子树是否是二叉平衡树。当这棵树的所有子树都为二叉平衡树时,该树为二叉平衡树。
算法流程: 整体分成两大步骤
1.判断树root是否平衡 : isBalanced(root)
(1)特例处理:当该树的根节点为空时,则直接返回true。
(2)返回值:所有子树都需要满足平衡树的性质,故以下三者需使用与逻辑&&进行连接
- abs(self.depth(root.left) - self.depth(root.right)) <= 1:判断当前子树是否是平衡树。
- self.isBalanced(root.left): 前序遍历递归,判断当前子树的左子树是否是平衡树。
- self.isBalanced(root.right): 前序遍历递归,判断当前子树的右子树是否是平衡树。
2.计算树root的最大高度:depth(root)(即上文思路中定义的获取该子树的最大高度的depth方法)
(1)终止条件:若root为空,即越过叶子结点,直接返回高度0。
(2)返回值:返回左 / 右子树的最大高度 + 1。
复杂度分析:
时间复杂度 为O(Nlog2N):最坏的情况下,isBalanced(root)需要遍历整棵树的所有节点,占用时间为O(N);判断每个节点的最大高度depth(root)则需要遍历各子树的所有节点,子树的节点数的复杂度为O(log2N)。(其中log2N是以2为底的N的对数)
空间复杂度O(N): 最差情况下(树退化为链表时),系统递归需要使用O(N)的栈空间。
Code
class Solution {
public boolean TreeNode(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 root) {
if (root == null) {
return 0;
}
return Math.max(depth(root.left), depth(root.right)) + 1;
}
}
PS:
暴力解法(自顶向下) 很容易想到且较容易实现,但是该方法会产生大量重复计算,占用大量内存空间,时间复杂度较高。
另一简便方法为 自底向上 解法,进行提前阻断,但是很难想到,其思路是对二叉树做前序遍历,从底至顶返回子树最大高度,若判定某子树不是平衡树则进行“剪枝”,直接向上返回。