PTA155。最小スタック

155.最小限のスタック

プッシュ、ポップ、およびトップ操作をサポートし、一定時間で最小の要素を取得できるスタックを設計します。

push(x)-要素xをスタックにプッシュします。
pop()-スタックの最上位にある要素を削除します。
top()-スタックの最上位要素を取得します。
getMin()-スタック内の最小の要素を取得します。

例:

入る:

["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

出力:

[null,null,null,null,-3,null,0,-2]

説明:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

促す:

pop、top 和 getMin 操作总是在 非空栈 上调用。


疑問に思う

この質問を見たとき、最初に考えたのは、現在の最小値を最小値で保存することでしたが、次に、minがスタックの最上位要素である場合、pop()を実行しても、minは最小値のままですか?タイトルに必要なのはO(1)O(1)O 1 時間以内にスタック内の要素の最小値取得するには、1分だけでは絶対に十分ではありません。minは最小値を1回しか保存できないため、一度ポップすると、minはスタック内の残りの要素の最小値にならない場合があります。予見される単調なスタックを学ぶために、コンテンツがここに戻ってきました

補助スタック

補助スタックは、その名前が示すように、補助スタックです。このスタックの機能は、現在のスタックの最小要素の値を保存することです。
ここに写真の説明を挿入

補助スタックのアイデアは新しいスタックを作成することです。レッツ・コールも最小のスタック。新しい要素はデータスタックに挿入されるたびに、それは最小のスタックの先頭の要素と比較している。新たに挿入されたデータがある場合未満最小スタックの最上位要素同じで、このデータを最小スタックに挿入します。

なぜそれをする必要がありますか?

まず、トピックを見て最小値を出力するように依頼します。次にmin_Stack、現在のデータスタックを保存するための最小値を作成します。最初に最初の要素を挿入し、次にそれを現在の最小値にする必要があります(結局、これは1つの要素にすぎません)。だからそれを挿入min_Stackします。次に、2番目の要素を挿入します。この新しい要素がmin_Stackスタックの一番上の要素よりも大きい場合、それは間違いなく現在最小の要素ではなく、挿入されません。言うことはありません。min_Stackスタックの一番上の要素以下の場合は、新規参入者が現在のスタックの最小要素であるため、最小のスタックに挿入されます。これによりmin_Stack、スタック内の要素がスタックの一番下から一番上に降順である必要があります(あまり正確ではありません。昇順ではない必要があります)(最小のスタックに新しく挿入された要素は、スタックの一番上の要素よりも小さい(または等しい)必要があるため)。次に、データスタックがスタックからポップされると、データスタックの最上位要素と最小スタック最上位要素が等しいかどうかが判断されます。等しい場合は同時にpop、そうでない場合はデータスタックのみが存在しますpop

判断するときになぜそれ以下なのですか?

たとえば、シーケンス5,4,3,3,3,3,5,4があり5,4,3、最小スタック挿入すると、次の新しいデータxはまだ3であり、挿入しないと仮定すると、最終的な最小スタックデータは5,4,3ですが、このプログラムのロジックは、最小スタック要素とデータスタックの最上位要素が等しい場合、両方のスタックは等しくなりpopます。pop最小スタックの最上位も3であるためpop、データスタックに3を指定すると、次のようになりますが、データスタックの最上位要素は3のままであり、最小です。スタック内のデータは5,4、つまり、データスタックに挿入された要素が同じである場合、それらも最小のスタックに挿入する必要があります。

プログラムのコードは次のとおりです。

class MinStack {
    
    
public:
    /** initialize your data structure here. */
    stack<int>data_Stack;
    stack<int>min_Stack;
    MinStack() {
    
    
    }
    void push(int x) {
    
    
        //如果最小栈为空或者最小栈栈顶元素 大于等于 x,那么就push
        if(min_Stack.empty() || min_Stack.top() >= x)min_Stack.push(x);
        data_Stack.push(x);
    }
    
    void pop() {
    
    
        if(min_Stack.top() == data_Stack.top())min_Stack.pop();
        data_Stack.pop();
    }
    
    int top() {
    
    
        return data_Stack.top();
    }
    
    int getMin() {
    
    
        return min_Stack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

最小スタックを理解する方法は?

実は、この一番小さいスタックは「予備のタイヤを上げる」と少し似ている気がします。私を一番愛してくれる女の子を見つけたいです。「女性のスタック」と「ガールフレンドのスタック」があります。「女性のスタック」は、私が空で出会うすべての女の子です。すべてのガールフレンドはここで見つける必要があります。「ガールフレンドスタック」の一番上の要素は、私の現在のガールフレンドです。 、今、次のガールフレンドはすべて「スペアタイヤ」です。今度は女の子が来ます、彼女は最初で唯一の彼女なので、私は女の子をpush天国まで「現在のガールフレンドスタック」進めるように置き、私の「女性スタック」をpush別のより良い女の子に与えました彼女は私をもっと愛しているので、私は彼女pushをトップガールフレンドとして「現在のガールフレンドスタック」に入れました、そしてボトムガールフレンドはすべて予備のガールフレンドです。私が新しいpush女の子に会うまで、私をもっと愛してくれる現在のガールフレンドがいない場合、現在のガールフレンドのスタックのトップは変わりません(私を愛している現在のガールフレンドがいなければ、なぜ彼女を新しいガールフレンドにする必要があります)、ですからpush後で来る女の子本当のガールフレンドを持っていない場合、彼らは私をもっと愛しています。彼らは私を愛しています。私の本当のガールフレンドは変わりませんが、私の「女性のスタック」の一番上の要素が私の現在のガールフレンドになるまで、彼女は変わりません。私を愛して、彼女は行きたがっています、そして私はしぶしぶ私の「現在のガールフレンドスタック」の一番上の要素をあきらめpopスペアタイヤがなくなるまで、、、まで正式に「スペアタイヤNo.1」を発売することができます。 、そして私の「女性のスタック」にはもうありません。悲しいかな、私は予備のタイヤがないことを知っていました、そしてそれが入ってきたら私は簡単でしょうreturn



新しいノード方式

ノードを作成し、現在のデータ値と最小値を保存します

これは実際には非常に理解しやすいので、これ以上は言いたくありません。コードを見てください。

class MinStack {
    
    
public:
    /** initialize your data structure here. */
    struct Node
    {
    
    
        int val;
        int min;
        Node(int v,int m):val(v),min(m){
    
    }; //相当于构造函数吧
    };
    stack<Node>sta;
    MinStack() {
    
    
    }
    void push(int x) {
    
    
        //把新元素与栈顶元素的min进行比较
        if(sta.empty())sta.push(Node(x,x));
        else sta.push(Node(x,min(x,sta.top().min)));
    }
    
    void pop() {
    
    
        sta.pop();
    }
    
    int top() {
    
    
        return sta.top().val;
    }
    
    int getMin() {
    
    
        return sta.top().min;
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

この方法は非常に優れており、上記よりも簡単です。効率はかなり高いと思います。

最初に上記の2つの方法を書いてみましょう。最小のスタック方法はかなり良いと思いますが、同様の問題がありますか?

おすすめ

転載: blog.csdn.net/qq_27168967/article/details/108808409