判断是不是平衡二叉树
判断是不是平衡二叉树
题目来源:牛客网:BM36 判断是不是平衡二叉树
题目描述
输入一棵节点数为
n
n
n 二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
示例:
样例二叉树如图,为一颗平衡二叉树
注:我们约定空树是平衡二叉树。
数据范围:
n
≤
100
n \le 100
n≤100, 树上节点的val值满足
0
≤
n
≤
1000
0 \le n \le 1000
0≤n≤1000
要求:空间复杂度
O
(
1
)
O(1)
O(1),时间复杂度
O
(
n
)
O(n)
O(n)
输入描述
输入一颗二叉树的根节点
返回值描述
输出一个布尔类型的值
示例1
输入:
{1,2,3,4,5,6,7}
返回值:
true
示例2
输入:
{}
返回值:
true
解题思路
二叉树递归
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。
而二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数不断进入子树。
思路
平衡二叉树任意节点的子树深度相差绝对值不会超过1,且每个子树都满足这个条件,那我们可以对每个节点找到两边的深度之后,
int deep(TreeNode root){
if (root == null){
return 0;
}
int left = deep(root.left);
int right = deep(root.right);
// 子树最大深度加上自己
return (left > right) ? left + 1 : right + 1;
}
判断是否两边相差绝对值超过1:
// 左子树深度减去右子树相差绝对值大于1
if (left - right) > 1 || (left - right)< -1:
return false;
然后因为每个子树都满足这个条件,我们还需要遍历二叉树每个节点当成一颗子树进行判断,而对于每个节点判断后,其子节点就是子问题,因此可以用递归:
IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
具体做法
- 第一个函数递归遍历二叉树所有节点
- 对于每个节点判断,调用第二个函数获取子树的深度
- 第二个函数递归获取子树的深度,只需要不断往子节点深度遍历,累加左右深度的较大值
- 根据深度判断该节点下的子树是否为平衡二叉树。
代码
Java
public class Solution{
// 计算该子树深度的函数
public int deep(TreeNode root){
// 空节点深度为0
if(root == null)
return 0;
// 递归计算左右子树的深度
int left = deep(root.left);
int right = deep(root.right);
// 返回子树的最大深度,并加上该节点本身
return (left > right) ? left + 1: right +1;
}
public boolean IsBalanced_Solution(TreeNode root){
if (root == null)
return true;
int left = deep(root.left);
int right = deep(root.right);
if (left - right >1 || left - right < -1){
return false;
}
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
}
}
Python
# -*- coding: utf-8 -*-#
# ----------------------------------------------
# Name: BM36.py
# Description: 判断是不是平衡二叉树
# Author: PANG
# Date: 2022/7/12
# ----------------------------------------------
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def depthOfTree(self, root: TreeNode):
if root is None:
return 0
left = self.depthOfTree(root.left)
right = self.depthOfTree(root.right)
# 子树最大深度加上自己
return left + 1 if left > right else right + 1
def IsBalanced_Solution(self, pRoot: TreeNode) -> bool:
if pRoot is None:
return True
left = self.depthOfTree(pRoot.left)
right = self.depthOfTree(pRoot.right)
# 左子树深度减去右子树相差绝对值大于1
if abs(left - right) > 1:
return False
# 左右子树还必须是平衡的
return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n为二叉树的节点数,第一个递归遍历二叉树所有节点,第二个递归查找深度最坏情况下(二叉树退化为链表)需要遍历二叉树所有节点
- 空间复杂度: O ( n ) O(n) O(n),递归栈最大深度为n.