1. 程式人生 > >劍指offer系列(39)平衡二叉樹

劍指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;   
    }

結果