剑指offer-平衡二叉树

题目描述

  • 输入一棵二叉树,判断该二叉树是否是平衡二叉树。
  • 牛客链接

解题思路

  • 这是一道关于二叉树经典套路问题,因为二叉树本身就是用递归定义的,所以关于二叉树的一些算法题大部分可用递归解。大致思路便是:根据题意,写一个递归函数,函数内部对左子树递归,收集信息,对右子树递归,收集信息,然后根据题意将左右子树信息整合,返回该树的信息,这也有点 分治 的思想在里面。
  • 要求该树是平衡二叉树,那么必须满足三个条件:
    • 左子树是平衡二叉树
    • 右子树是平衡二叉树
    • 左右子树的高度之差 <= 1

这便体现出了递归的含义,验证本身是否二叉平衡树,需要知道它的左右子树是否是平衡二叉树,所以我们最初的思路是需要定义一个函数 isBalanced,传入该树的根节点,返回该树是否是平衡二叉树,在函数内部对左右子树递归调用自身。

  • 但是,二叉搜索树还要求 左右子树的高度之差 <= 1,所以,我们还必须让该函数验证是否平衡二叉树的同时,返回该树的高度。因为是用java实现,没有指针的概念,所以返回两个参数可以有以下两个途径:
    • 第二个返回值,作为参数,以数组的形式传递
    • 将两个返回值,包装成一个类,返回对象(当然,如果返回值类型相同,可以返回数组)
  • 该题还有一种代码更加简洁的方法:
    • 是直接对求二叉树的高度的递归函数进行改写,传入树的根节点,递归函数返回该树高度。
    • 同样对左右子树递归,求左右子树的高度;然后在整合信息时,如果两树高度之差不是 <= 1或者左子树高度为 -1 或者右子树高度为 -1 ,则将 -1 设为当前树的高度,返回。

经验教训

  • 二叉树经典递归套路(分治)
  • java如何返回多个值(如何实现指针的作用)

代码实现

  • 解法一:
import java.util.*;
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        return isBalanced(root).isB;
    }

    //isBalanced():判断传入的树是否是平衡二叉树,若是,返回true和树的正确高度;否则,返回false树的高度设为0
     public Result isBalanced(TreeNode root) {
         //base case: 
        if(root == null) {
           return new Result(true, 0); 
        }
         //递归,收集左子树信息
        Result leftRes = isBalanced(root.left);
         //如果左子树不是平衡二叉树,直接返回,此时,树的高度定义为什么都可
        if (! leftRes.isB) {
            return  new Result(false, 0);
        }
        //递归,收集左子树信息 
        Result rightRes = isBalanced(root.right);
         //如果右子树不是平衡二叉树,直接返回,此时,树的高度定义为什么都可
        if (! rightRes.isB) {
            return  new Result(false, 0);
        }
         //根据题意,整合左右子树信息:
        if (Math.abs(leftRes.depth-rightRes.depth) > 1) {
            return  new Result(false, 0);
        }
         //满足平衡二叉树的条件,返回true,并将当前树高度设为 左右子树高度最大值+1
        return new Result(true, Math.max(leftRes.depth, rightRes.depth) + 1);
    }

    //将返回结果定义为一个类
    class Result {
        boolean isB;//该树是否是平衡二叉树
        int depth;//该树高度

        public Result(boolean isB, int depth) {
            this.isB = isB;
            this.depth = depth;
        }
    }
}
  • 解法二: 递归函数返回当前树的高度,根据高度判断是否平衡二叉树:
import java.util.*;
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        return treeDepth(root) != -1;
    }

    //改编自求二叉树的高度,传入一个树的根节点,如果该树是平衡二叉树,返回该树实际高度,否则,返回-1
    public int treeDepth(TreeNode root) {
        if(root == null) {
           return 0; 
        }
        //递归左子树
        int leftDepth = treeDepth(root.left);
        //如果左子树不是平衡二叉树,那么当前树肯定也不是平衡二叉树,直接返回-1
        if (leftDepth == -1) {
            return -1;
        }
        //递归右子树
        int rightDepth = treeDepth(root.right);
        //如果右子树不是平衡二叉树,或者左右子树高度之差大于1,那么当前树肯定也不是平衡二叉树,直接返回-1
        if (rightDepth == -1 || Math.abs(leftDepth - rightDepth) > 1) {
            return -1;
        }
        //是平衡二叉树,返回该树实际高度
        return Math.max(leftDepth, rightDepth) + 1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值