問題の説明
二分木のルートノードを入力して、その木が平衡二分木であるかどうかを判断します。二分木のノードの左右のサブツリーの深さが1を超えない場合、それは平衡二分木です。
例1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
例2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。
制限:
0 <= 树的结点个数 <= 10000
問題解決のアイデア:注文後の走査+剪定(下から上へ)
二分木のポストオーダートラバーサルを実行し、サブツリーの深さを下から上に戻すという考え方です。特定のサブツリーがバランスの取れたツリーではないと判断された場合、「剪定」されて真上に戻ります。
アルゴリズムフロー:
recur(TreeNode p)関数
戻り値:
ノードルートの左右のサブツリー間の深度差の絶対値が1以下の場合、現在のサブツリーの深度、つまり左右のサブツリーの最大深度が返されます。ノードルートの+1(max(left、right)+ 1);
ノードルートの左/右サブツリーの深さの差の絶対値> = 2の場合:-1を返します。これは、このサブツリーがそうではないことを意味します。バランスの取れた木。
終了条件:
ルートが空の場合:リーフノードが交差しているため、高さが0であることを意味します。
左(右)サブツリーの深さが-1の場合:このツリーの左(右)サブツリーはバランスが取れていません。ツリー、つまり剪定は、直接-1を返します。
class Solution {
public boolean isBalanced(TreeNode root) {
//返回-1表示不是平衡二叉树
if(recur(root)==-1){
return false;
}else{
return true;
}
}
public int recur(TreeNode p){
//如果该子树为空,直接返回0
if(p==null){
return 0;
}
int leftheight=recur(p.left); //计算左子树的深度
int rightheight=recur(p.right); //计算右子树的深度
//如果左右子树有一个为-1(代表不平衡)或者左右子树的高度差的绝对值大于1,返回-1
if(leftheight==-1 || rightheight==-1 || Math.abs(rightheight-leftheight)>1){
return -1;
}else{
//否则,返回左右子树的最大值+1
return Math.max(leftheight,rightheight)+1;
}
}
}