一、题目描述:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:true
示例 2:
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false
示例 3:
输入:root = []
输出:true
二、思路分析:
有自顶向下和自底向上两种思路,可以分别看成先序遍历和后续遍历。 自顶向下:从根节点向下遍历所有节点,并且计算出每个节点的深度,如果有左右字数高度大于1的说明不是平衡二叉树
- 时间复杂度 O(Nlog2N): 最差情况下, isBalanced(root) 遍历树所有节点占用 O(N),判断每个节点的最大高度 getTreeHeight(root) 需要遍历 各子树的所有节点 ,子树的节点数的复杂度为O(log2N)
- 空间复杂度 O(N): 最差情况下(树退化为链表时),系统递归需要使用 O(N) 的栈空间。
自底向上:后续遍历,先访问左右子书,再判断根节点。这样的遍历方式避免了重复计算子树的高度
- 时间复杂度 O(N): N 为树的节点数;最差情况下,需要递归遍历树的所有节点。
- 空间复杂度 O(N): 最差情况下(树退化为链表时),系统递归需要使用 O(N) 的栈空间。
三、AC 代码:
class Solution {
fun isBalanced(root: TreeNode?): Boolean {
return solution2(root)
}
// 后续遍历
fun solution2(root: TreeNode?): Boolean {
return depth(root) != -1
}
fun depth(root: TreeNode?): Int {
if (root == null) {
return 0
}
var left = depth(root.left)
if (left == -1) {
return -1
}
val right = depth(root.right)
if (right == -1) {
return -1
}
if (Math.abs(left - right) < 2) {
return Math.max(left, right) + 1
} else {
return -1
}
}
fun solution1(root: TreeNode?): Boolean {
if (root == null) {
return true
}
return isBalanced(root.left) && isBalanced(root.right)
&& Math.abs(getTreeHeight(root.left) - getTreeHeight(root.right)) <= 1
}
private fun getTreeHeight(root: TreeNode?): Int {
if (root == null) {
return 0
}
return Math.max(getTreeHeight(root.left), getTreeHeight(root.right)) + 1
}
}
四、总结:
如果直接考二叉树的前中后序遍历,应该很多人都能知道。相当一部分题就是变着花样考察二叉树的遍历。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情