オファーその後のトラバーサル順序は二分探索木を受賞します

1.トピック

整数配列を入力して、アレイは、バイナリ検索ツリーをトラバースした後決意の結果ではありません。もし出力はい、そうでなければ出力号 任意の2つの数の入力配列が異なっていると仮定する。

出典:安全オファー証明
リンク:https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

2.私の問題の解決

バイナリ検索ツリーバイナリツリー内のすべての値は、ノードの任意の左の部分木は、ノードの値より小さく、右サブツリー内のすべての値は、ノードの値よりも大きい、バイナリツリーは二分探索木と呼ばれています。
再帰的に二分探索木の性質に応じて解決しました。

class Solution {
    bool IsBST(vector<int> data,int l,int r){
        if(l>=r)return true;
        int pivot = data[r];
        int i=l;
        for(;i<r;i++)
            if(data[i]>pivot)break;
        int mid=i;
        for(;i<r;i++)
            if(data[i]<pivot)return false;
        return IsBST(data,l,mid-1) && IsBST(data,mid,r-1);
    }
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int len = sequence.size();
        if(len==0)return false;
        return IsBST(sequence,0,len-1);
    }
};

3.誰か他の人の問題解決

3.1最大および最小境界方法

リンク:https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd?answerType=1&f=discussion
出典:牛の旅客ネットワーク
以下は、コピーであり、コンテンツを貼り付けます。
方法2:最大値と最小境界制約方法
、我々は助けることはできませんが、思うだろうという貪欲なので、より良い方法はありますか?O(n)を、さらにはO(LOGN)?

適切なトラバーサル順序以来、私たちは故意に、それは当然のことながら、それゆえそう思う、その有効性を決定するために、すべての要素を通過するためにバインド、この問題の時間計算量が低くO(n)とのバインドする必要があり、任意の位置に改ざんすることができます、アイデアはあなたがよりよい解決策のアイデアを持っている場合は、頻繁に間違っている、または提案手法の病気の場所を見つけ、私に教えてくださいになる傾向があり、一緒に学び、一緒に進行!

私たちのアイデアは、シーケンスが横断されたときにということであるだけ傾向を減らすことができ、そして現在の要素に基づいて、左の増分の過去の履歴に記録された情報は、シーケンスそれの合法性について判断を下すことができますか?二分探索木の主な特徴は次のとおりです。のために:すべてのサブツリーのために「左のサブツリー<ルート<右のサブツリーは、」我々は、この重要な機能、すなわち、表現の別の形式に変換することができることを見出していますその右サブツリーが下限値(MIN)であるが、そのルート制約、それについての範囲サブツリーいかなるサブツリーは、サブツリーのルートのルートは、その左の部分木の上限(最大)値です。だから我々は、ルートノードから下に行くを開始した場合、そのノードのシニア祖父母シーケンスは、低レベルのノードの形成を維持する下限値に制約を横断していない、長い下のノードがこの制約に違反しないようとして、それはそうでない場合、正当なもので、シーケンスが可能違法である(それは正当であり得る、後述)。

帰りがけ順の機能のいくつかは、右から左に、我々は最後の要素を横断した後、ルートノードであるので、その逆はルートから葉に、右のサブツリーと同等のアクセスで、逆の順序で所定の配列を訪問することを決めたので私たちは先祖ノードの制約上の子ノードの正当性の下限を決定するために使用する需要を満たすルートから葉に、サブツリーアクセス順序を残しました。

もし現在の要素が右の子の要素であることを示している(逆刻み)での現在の要素>要素、この時間:
現在の要素の画期的な最大キャップの制約の場合、祖父母の存在下で、その「左部分木>ルート」、探索木の定義に反して(その後、サブ世代7> 5祖父母が最大制約がある、7に値4を把握しようとすると、探索木は真ではないが)
。そうでなければ、現在の要素は、正当な使用であり、上限値の間にあります素子更新分の上限と下限、最大
下で又は要素の左側に現在の要素を示す要素<現在の要素(逆降順)、もし、この時間:
現在の要素分の休憩と下限場合、左当事者は、ここでは(なぜなら、最大のレコードが2本の木の共通の親までクリアし、その後、私たちは分を持っている必要があります(左部分木行くに行き、右の子の訪問の上にある)木のジャンプはそれを呼び出します2つのツリーの異なるブランチ6-> 3に示すように制約を破るが、下限が、)、再カウントしなければならない位置し、これは正当であるれている
それ以外の場合、現在の要素が落ちます 下限の間に、子供が要素の上に残され、上限と下限の分の使用上の要素の更新、最大
その後、我々はリミットの店舗情報、ルートスタック、最小スタック、およびスタックを使用する最大スタック理由に3つのスタックを使用通常の状況下では、離れ根から葉まで、我々はそれだけで、最新の最小値、最大値制約を使用する必要がありますが、状況ツリージャンプが発生した場合、現在の要素<分は、その後、履歴情報を使用する必要があるため、スタックの三つの要素、現在の要素>分までスタック。スタックは、(左サブツリー更新最大に)スタックのために、スタック、主根の親ノードの値を保存するために使用されます。最初は、正と負の無限大の制限デフォルトにプッシュする必要があります。
ここに画像を挿入説明
複雑性分析:状況が注文スタック内のアクセス情報、スタックの値の先頭に各のみアクセスするために左に右から順その後、アウトスタック(木ジャンプ)のない場合には、複雑さはO(n)は、ツリーがジャンプに表示された場合今度は、あなたは(Oの複雑さ、そのため、最悪の場合は、すべてのノードが操作をポップを通過することです、繰り返しスタックノードが表示されないプッシュするすべてのスタックによって生成された右部分木の情報が、同じような状況が必要N)O(2N)となります。アルゴリズムの時間計算量は、最終O(N)である定数を無視し、空間的複雑度はO(n)は
以上のコンテンツをコピーして貼り付けます。

例えば:2,4,3,6,9,8,5

5
3
2
4
8
6
9
シーケンス ルート(スタック) 分(スタック) 最大(スタック)
5 5 MIN MAX
8 5,8 MIN、5 MAX、MAX
9 5,8,9 MIN、5.5 MAX、MAX、MAX
6 5,8,9,6 MIN、5,5,5 MAX、MAX、MAX、9
3 5,3 MY、MY MAX、5
4 5,3,4 MIN、MIN、3 MAX、5,5
2 5,3,2 MY、MY、MY MAX、5,3
class Solution {
    stack<int> min,max,root;
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int len = sequence.size();
        if(len==0)return false;
        min.push(INT_MIN);
        max.push(INT_MAX);
        root.push(sequence[len-1]);
        for(int i=len-2;i>=0;i--){
            //右子树
            if(sequence[i]>sequence[i+1]){
                if(sequence[i]>max.top())return false;
                max.push(max.top());
                min.push(root.top());
                root.push(sequence[i]);
            }
            else{//左子树
                //弹出之前的右子树及根
                while(sequence[i]<min.top()){
                    root.pop();
                    max.pop();
                    min.pop();
                }
                max.push(root.top());
                min.push(min.top());
                root.push(sequence[i]);
            }
        }
        return true;
    }
};

3.2partition

バイナリ検索ツリートラバーサルフォローアップ:いくつかの大きないくつかの小さな値+値+中間値
パーティション内の高速ロウ:大型のために小さな値+値+値の中央部分
えっ?多分それはああのように思えます!その後のバイナリ検索ツリートラバーサルシーケンス場合は、そのpartition操作は、順序を変更することはありません。
注:安定に使用してみpartition不安定な動作をpartition特定の問題につながる可能性があり、安定していない、元のシーケンス番号の相対位置を変更します。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int len = sequence.size();
        if(len==0)return false;
        int root = sequence[len-1];
        vector<int> vec=sequence;
        stable_partition(vec.begin(),vec.end(),[root](int x){return x<root;});
        return vec==sequence;
    }
};

4.まとめとリフレクション

公開された32元の記事 ウォンの賞賛0 ビュー406

おすすめ

転載: blog.csdn.net/weixin_43951240/article/details/104069694