タイトルの説明:
整数配列を入力して、その配列が二分探索木のポストオーダートラバーサルの結果であるかどうかを判別します。
そうである場合はtrueを返し、そうでない場合はfalseを返します。入力配列内の任意の2つの数値が互いに異なると仮定します。
(追記:空の木は二分探索木ではないことに同意します)
例1
入力
[4,8,6,12,16,14,10]
戻り値
true
アイデア分析:
二分探索木の特徴は次のとおりです。現在のノードに左のサブツリーがある場合、左のサブツリーの各ノードの値は現在のノードの値以下です。現在のノードに右のサブツリー、次に右のサブツリーの値各ポイントの値が現在のノードの値よりも大きい;
もう一度分析してみましょう:ツリーの順序後のトラバーサルの特性は何ですか?トラバーサルの順序は左でなければなりません最初にサブツリー、次に右側のサブツリー、最後にルートノードです。
これらの2つの特性によると、後続のトラバーサルシーケンスでは、最後の値がルートノードであることがわかります。ルートノードに加えて、シーケンスは2つの部分に分割されます。
ルートノードより大きい最初の値を分割線として使用します。ルートノードより大きい最初の値の後のシーケンスは、ルートノードの右側のサブツリーです;
これらの右側のサブツリーの値で判断してください:
現在のノードが平衡二分木の特性を満たしていることを意味する場合、それぞれがルートノードよりも大きくなります。次に、左側のサブツリーと右側のサブツリーに対してそれぞれこれを行います。- 1つが満たされない場合、
条件を満たすのは後続のトラバーサルではありません。
ノードをトラバースできなくなるまで、2つの操作を繰り返します。
コード表示:
/*
*输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
* 如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。
* (ps:我们约定空树不是二叉搜素树)
* */
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
//二叉搜索树的特点,每个根节点都满足:节点的左子树都小于等于节点的值;节点的右子树都大于根节点的值
//int index=sequence.length-1;
if(sequence.length == 0){
return false;
}
return traverse(sequence,0,sequence.length-1);
}
public boolean traverse(int[] sequence,int start,int end){
if(start>=end){
return true;
}
int key=sequence[end];
int i=0;
for( i=start;i<end;i++){
if(sequence[i]>key)
break;
}
for(int j=i;j<end;j++){
if(sequence[j]<key){
return false;
}
}
return traverse(sequence,start,i-1)&&traverse(sequence,i,end-1);//在子树中遍历,除去根节点
}
}