劍指offer系列(39)平衡二叉樹
阿新 • • 發佈:2019-02-04
題目描述
輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
思路分析
方法一:平衡二叉樹定義:二叉樹中任意節點的左,右子樹深度不超過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
結果:時間比方法一長,是因為牛客上的測試樣例少,只有7個,相對於遍歷,new操作也要耗費時間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; }
方法三 輔助陣列
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;
}
結果