問題の説明
二分木が与えられた場合、重複する値を持つノードはありません。二分木が検索二分木であるか、完全な二分木であるかを判断してください。
説明を入力してください:
ツリーを入力してください
出力の説明:
ブール型の配列を出力します。最初の配列が二分探索木であるかどうか、2番目の配列が完全な二分木であるかどうかです。
例
例1
{2,1,3}と入力します
出力
[true、true]
ソリューション
分析
-
二分探索木の判断:
- 間違った考え:各サブツリーが二分探索木の条件を満たしているかどうかを再帰的に判断することは不可能です
3 / \ 2 5 / \ 1 4
- 正しい考え:決定する左側のサブツリーの最大値と右側のサブツリーの最小値を制限することにより、ノードを1回トラバースするだけで済みます。
-
完全な二分木の判断
- プロパティ:nノードの完全な二分木の深さはlog2n +1です
- 木の高さを判断して完全な二分木かどうかを判断します。左側のサブツリーと右側のサブツリーの最大深度差は1を超えません。
方法
- 二分探索木:再帰を介して、制限された最小値と最大値を渡して、二分探索木の性質に準拠しているかどうかを判断します
- 完全な二分木:左のサブツリーと右のサブツリーの最大の高さ、左のコントラストの差を計算することにより、差は1より大きくなり、そうではありません。
コード
public class Solution {
/**
* @param root TreeNode类 the root
* @return bool布尔型一维数组
*/
public boolean[] judgeIt (TreeNode root) {
// write code here
boolean[] result = new boolean[]{
false, false};
result[0] = isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
result[1] = isBalance(root);
return result;
}
// 错误思路:判断是否是二叉搜索树
// 3
// / \
// 2 5
// / \
// 1 4
private boolean isBinarySearch (TreeNode root) {
if (root == null) {
return true;
}
int val = root.val;
if (root.left != null && val < root.left.val) {
return false;
}
if (root.right != null && val > root.right.val) {
return false;
}
return isBinarySearch(root.left) & isBinarySearch(root.right);
}
// 通过限定每个子节点的范围
private boolean isBST(TreeNode root, int min, int max) {
if(root == null)
return true;
if(root.val < min || root.val > max)
return false;
// 左节点要求小于根节点的值,最大值发挥作用;右节点要求大约根节点的值,最小值发挥作用
return isBST(root.left, min, root.val - 1) && isBST(root.right, root.val + 1, max);
}
// 判断是否是完全二叉树
private boolean isBalance(TreeNode root) {
boolean[] res = new boolean[1];
res[0] = true;
getHeight(root, res);
return res[0];
}
private int getHeight(TreeNode root, boolean[] i) {
if (i[0] == false) {
return 0;
}
if (root == null) {
return 0;
}
// 判断左右节点的高度
int l = getHeight(root.left, i) + 1;
int r = getHeight(root.right, i) + 1;
if (Math.abs(r - l) > 1) {
i[0] = false;
}
return Math.max(l, r);
}
}
テストしたい場合は、Niuke.comのリンクに直接アクセスしてテストを行うことができます