day38 JZ79 判断是不是平衡二叉树(Java)

120 阅读2分钟

题目来源: JZ79 判断是不是平衡二叉树

题目描述:

  • 描述: 输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。
    • 在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树。平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
    • 样例解释:
      • D55A07912354B3AB7E9F2F5EA27CB7D6.png
      • 样例二叉树如图,为一颗平衡二叉树
      • 注:我们约定空树是平衡二叉树。 数据范围: n≤100,树上节点的val值满足0≤n≤1000 要求: 空间复杂度O(1),时间复杂度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);
        
  • 具体做法:
    • step 1:第一个函数递归遍历二叉树所有节点。
    • step 2:对于每个节点判断,调用第二个函数获取子树深度。
    • step 3:第二个函数递归获取子树深度,只需要不断往子节点深度遍历,累加左右深度的较大值。
    • step 4:根据深度判断该节点下的子树是否为平衡二叉树。
  • 图示:
    • B894208C51B667B8FA70DD13C43DF19E.gif

具体实现:

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);
        //左子树深度减去右子树相差绝对值大于1
        if(left - right > 1 || left - right < -1) 
            return false;
        //同时,左右子树还必须是平衡的
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
}