剑指offer系列(39)平衡二叉树

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。


思路分析

方法一:平衡二叉树定义:二叉树中任意节点的左,右子树深度不超过1

             参考之前二叉树的深度,利用递归,依次求出深度,比较即可得出答案

方法二:构造内部类

             方法一中,一个节点作为子节点时被遍历,作为根节点时同样被遍历,如此,有太多重复的遍历次数

             如果用后序遍历的方式遍历二叉树的每个节点,那么在遍历到一个节点之前就已经遍历了它的左、右子树。只要在遍历每个节点的时候记录                                        它的深度,就可以一边遍历一边判断每个节点是不是平衡的

方法三:利用辅助数组,模拟引用传递 思路同方法二

方法四:方法二、三都是通过模拟引用传递的方式,通过方法三,我们可以知道,此题辅助数组中只存贮了一个元素,既然如此,那直接定义一个全局变量,也能完成此题


代码

方法一

public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) {  //边界条件
			return true;
		}
        int left = TreeDepth(root.left);  //记录左子树深度
        int right = TreeDepth(root.right);  //记录右子树深度
        int diff = left -right;  //深度差
        if (diff>1 || diff<-1) {  //深度差大于1则不是平衡二叉树
			return false;
		}
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);  //依次遍历左子树和右子树
    }
	
	public int TreeDepth(TreeNode root) {  //求出树的深度
		if (root == null) {
			return 0;
		}
		int left = TreeDepth(root.left);
		int right = TreeDepth(root.right);
		return Math.max(left, right)+1;
	}

结果



方法二 构造内部类是因为java是值传递,要正确记录到depth不能直接在参数列表里加入int depth

public boolean IsBalanced_Solution(TreeNode root) {
        int depth = 0;  //初始化深度
        return IsBalanced(root, new create());
    }
	private class create{
		int x;
	}
	public boolean IsBalanced(TreeNode root,create depth){  
		if (root == null) {  //边界条件
			depth.x = 0;
			return true;
		}
		create left = new create();
		create right = new create();
		if (IsBalanced(root.left, left) && IsBalanced(root.right, right)) {  //递归,先遍历左子树,再右子树,即完成后序遍历
			int diff = left.x - right.x;  
			if (diff<=1 && diff>=-1) {  //判断是否平衡
				depth.x = 1 + (left.x>right.x ? left.x : right.x);  //记录深度
				return true;
			}
		}
		return false;
	}
结果:时间比方法一长,是因为牛客上的测试样例少,只有7个,相对于遍历,new操作也要耗费时间



方法三 辅助数组

public boolean IsBalanced_Solution(TreeNode root) {
			int depth[] = new int [2];
			return isBalanced(root, depth);   
	    }
		public boolean isBalanced (TreeNode root, int[] depth){
			if (root == null) {
				depth[0] = 0;
				depth[1] = 0;
				return true;
			}
			boolean left=isBalanced(root.left,depth);
			int leftdepth=depth[0];
			boolean right=isBalanced(root.right,depth);
			int rightdepth=depth[0];
			depth[0]=Math.max(leftdepth+1,rightdepth+1);
			if(left&&right&&Math.abs(leftdepth-rightdepth)<=1)return true;
			return false;
		}


方法四 全局变量

private boolean isBalanced=true;
    public boolean IsBalanced_Solution(TreeNode root) {
        getDepth(root);
        return isBalanced;
    }
    public int getDepth(TreeNode root){
        if(root==null)
            return 0;
        int left=getDepth(root.left);
        int right=getDepth(root.right);
         
        if(Math.abs(left-right)>1){
            isBalanced=false;
        }
        return right>left ?right+1:left+1;   
    }

结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值