L'épée fait référence à la pile Offer30 contenant la fonction min (pile monotone)

Description du problème

Définissez la structure de données de la pile. Veuillez implémenter une fonction min qui peut obtenir le plus petit élément de la pile dans ce type. La complexité temporelle de l'appel de min, push et pop est O (1) dans cette pile.

Exemple:

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

Idées de résolution de problèmes:

Le problème de la pile monotone peut être lancé à partir de la pensée conventionnelle, puis extraire une partie de la nature du problème
Pensée conventionnelle: la complexité des fonctions push () et pop () de la pile ordinaire est O (1); et la valeur minimale de la fonction stack min () Besoin de parcourir toute la pile, la complexité est O (N) .
Difficultés dans cette question: réduire la complexité de la fonction min () à O (1) O (1), ce qui peut être obtenu en construisant une pile monotone;
pile de données A: la pile A est utilisée pour stocker tous les éléments, assurant push ( ) sur la pile et pop La fonction pop (), récupère la logique normale de la fonction top () de la pile.
Pile monotone B: La pile B stocke tous les éléments non strictement descendants dans la pile A, puis le plus petit élément de la pile A correspond toujours à l'élément supérieur de la pile B, c'est-à-dire que la fonction min () n'a besoin que de renvoyer l'élément supérieur de B pile .
Par conséquent, il suffit d'essayer de maintenir les éléments de la pile B pour maintenir un ordre décroissant non strict (du bas de la pile au sommet de la pile), et la complexité O (1) de la fonction min () peut être réalisé.

push (x): poussez d'
abord l' élément dans la pile A, si la pile B est vide, poussez-le simplement directement dans la pile B, sinon il ne sera poussé que lorsque l'élément est plus petit (ou égal) que l'élément supérieur actuel de la pile Dans la pile B. De cette manière, on peut garantir que la pile B décroît de manière monotone du bas de la pile vers le haut de la pile .

Point douteux: pourquoi seul l'élément inséré est poussé dans la pile B alors qu'il est plus petit que l'élément courant en haut de la pile .
Supposons que l'élément supérieur de la pile B soit notre valeur minimale min, et cette valeur minimale min se trouve également dans la pile A lorsque l'élément x est inséré.
Si x est plus grand que l'élément supérieur de la pile, il n'est pas nécessaire de l'insérer dans la pile B. À ce stade, la valeur minimale de la pile A est toujours min. Puisque la pile est le dernier entré, premier sorti, x sort de la pile avant min, et est plus petit s'il n'est pas inséré. Avant l'élément de, le plus petit élément de la pile peut toujours être conservé comme min jusqu'à ce que min soit affiché. Donc,
si x est plus petit que l'élément supérieur de la pile, insérez x dans la pile B. À ce stade, la valeur minimale de la pile A est x. Lorsque x est popped, l'élément x dans la pile B sera également popped, et min devient La valeur minimale de la pile A.
Le point clé est que les "valeurs minimales" dans la pile B sont sautées dans le même ordre que ces "valeurs minimales" sont sautées dans la pile A.
pop (): pop d'
abord l'élément supérieur de la pile A. Si l'élément est l'élément supérieur de la pile B, alors l'élément supérieur de la pile B sera également poppé.
min ()
retourne directement à l'élément supérieur de la pile B..
top ()
renvoie l'élément supérieur de la pile A.

Code d'implémentation

class MinStack {
    
    
    public Stack<Integer> stack1;           //元素栈
    public Stack<Integer> stack2;           //单调栈
    /** initialize your data structure here. */
    public MinStack() {
    
    
        stack1=new Stack<Integer>();
        stack2=new Stack<Integer>();
    }
    
    public void push(int x) {
    
    
        stack1.push(x);     
        //只有栈2为空或者x比栈2的栈顶元素的值还要小(一定要包含等于)的时候,才会将x加入栈2中
        if(stack2.empty() || x<=stack2.peek()){
    
    
            stack2.push(x);
        }
    }
    
    public void pop() {
    
    
        int ele=stack1.pop();
        //当栈2不为空,且弹出的元素恰好等于栈2的栈顶元素值时,就把栈2的栈顶元素值也跟着弹出
        if(!stack2.empty() && ele==stack2.peek()){
    
    
           stack2.pop();
        }
    }
    
    public int top() {
    
    
        //直接返回栈1的栈顶元素值即可
        return stack1.peek();
    }
    
    public int min() {
    
    
        //直接返回栈2的栈顶元素值即可
        if(!stack2.empty()){
    
    
            return stack2.peek();
        }
        return 0;
    }
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_39736597/article/details/113816319
conseillé
Classement