🥉Easy
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过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
。
题解
虽然是Easy,还是不知道怎么去写!树方面太差了吧😤😤😤😤
这道题中的平衡二叉树的定义是:二叉树的每个节点的左右 子树的高度差的绝对值不超过 11,则二叉树是平衡二叉树。根据定义,一棵二叉树是平衡二叉树,当且仅当其所有子树也都是平衡二叉树,因此可以使用递归的方式判断二叉树是不是平衡二叉树,递归的顺序可以是自顶向下或者自底向上。
自顶向下的递归
定义高度函数height,用于计算二叉树中任一节点p的高度
有了计算节点高度的函数,就可以判断二叉树是否平衡。具体操作类似于二叉树的先序遍历。即对于当前遍历的节点,首先计算左右子树的高度,如果左右子树高度差绝对值不超过1,再分别递归遍历左右子节点,并判断左子树和右子树是否平衡。
Python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def height(root: TreeNode) -> int:
if not root:
return 0
return max(height(root.left), height(root.right)) + 1
if not root:
return True
return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
复杂度分析
- 时间复杂度:
其中 n 是二叉树中的节点个数。
最坏情况下,二叉树是满二叉树,需要遍历二叉树中的所有节点,时间复杂度是 。对于节点 p,如果它的高度是 d,则 height(p) 最多会被调用 d 次(即遍历到它的每一个祖先节点时)。对于平均的情况,一棵树的高度 h满足
,因为 d≤h,所以总时间复杂度为
。对于最坏的情况,二叉树形成链式结构,高度为
,此时总时间复杂度为
空间复杂度:,其中 nn 是二叉树中的节点个数。空间复杂度主要取决于递归调用的层数,递归调用的层数不会超过 n。
自底向上的递归
自顶向下的递归中对于同一节点,函数会被重复调用。如果使用自底向上的方法,则对于每个节点,函数
只会被调用一次。
自底向上类似于后序遍历,对于当前遍历到的节点,先递归判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,就返回其高度,否则返回-1.如果存在一棵子树不平衡,则整个二叉树一定不平衡。
Python
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def height(root: TreeNode) -> int:
if not root:
return 0
leftHeight = height(root.left)
rightHeight = height(root.right)
if leftHeight == -1 or rightHeight == -1 or abs(leftHeight - rightHeight) > 1:
return -1
else:
return max(leftHeight, rightHeight) + 1
return height(root) >= 0
复杂度分析
时间复杂度:
,其中 nn 是二叉树中的节点个数。使用自底向上的递归,每个节点的计算高度和判断是否平衡都只需要处理一次,最坏情况下需要遍历二叉树中的所有节点,因此时间复杂度是
。
空间复杂度:
,其中 n 是二叉树中的节点个数。空间复杂度主要取决于递归调用的层数,递归调用的层数不会超过 n。