今日、私はインタビューを行いました。そこでは、バイナリツリーを取得し、それがバイナリ検索ツリーでもある場合はtrueを返すプログラムを作成するように依頼されました。
私のアプローチ1:順序走査を実行し、要素をO(n)時間で保存します。今度は要素の配列/リストをスキャンし、iの要素をチェックします番目 インデックスが(i + 1)の要素より大きい番目 インデックス。そのような状態が発生した場合は、falseを返してループを抜けます。 (これにはO(n)時間かかります)。最後にtrueを返します。
しかし、この紳士は私に効率的な解決策を提供することを望んでいました。試しましたが、BSTであるかどうかを確認するには各ノードをチェックする必要があるため、失敗しました。
さらに、彼は再帰について考えるように私を指していた。私のアプローチ2:任意のノードN N-> leftが<NおよびN-> right> Nであり、Nの左ノードの順序後継がNより小さく、順序後継がある場合、BTはBSTですNの右ノードのNはNより大きく、左および右のサブツリーはBSTです。
しかし、これは複雑になり、実行時間は良くないようです。最適なソリューションを知っている場合は助けてください。
これは、次の答えを持つかなりよく知られた問題です。
public boolean isValid(Node root) {
return isValidBST(root, Integer.MIN_VALUE,
Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
if(node == null)
return true;
return node.value > l
&& node.value < h
&& isValidBST(node.left, l, node.value)
&& isValidBST(node.right, node.value, h);
}
再帰呼び出しは、サブツリーノードがその祖先の範囲内にあることを確認します。これは重要です。すべてのノードが一度検査されるため、実行時間の複雑さはO(n)になります。
もう1つの解決策は、特にバイナリツリーが入力として提供されていることを既に知っているため、順序のトラバーサルを行い、シーケンスがソートされているかどうかを確認することです。
@Dhruvが提供する答えは良いものです。これに加えて、O(n) time。
このアプローチでは、前のノードを追跡する必要があります。各再帰呼び出しでは、現在のノードデータで以前のノードデータをチェックします。現在のノードデータが前のものよりも少ない場合、falseを返します
int isBST(node* root) {
static node* prev = NULL;
if(root==NULL)
return 1;
if(!isBST(root->left))
return 0;
if(prev!=NULL && root->data<=prev->data)
return 0;
prev = root;
return isBST(root->right);
}
boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
if(node == null){
return true;
}
boolean left = isBinarySearchTree(node.getLeft(), min, node.getValue());
boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);
return left && right && (node.getValue()<max) && (node.getValue()>=min);
}
コメントを募集しています。ありがとう。
2番目のアプローチは正しいと思います。ツリーは再帰的に横断できます。各反復で、現在のサブツリーの下限と上限を保存できます。ルートxのサブツリーをチェックし、サブツリーの境界がlとhである場合、必要なのはl <= x <= hであり、左のサブツリーを境界lとxで、右をチェックすることだけです。境界xとhを持つもの。
これはO(n)複雑さを持ちます。これは、ルートから開始し、各ノードがサブツリーのルートとして一度だけチェックされるためです。また、O(h)再帰呼び出しのメモリ。hはツリーの高さです。