web-dev-qa-db-fra.com

concevoir une pile telle que getMinimum () devrait être O(1)

C'est une question d'entrevue. Vous devez concevoir une pile contenant une valeur entière telle que la fonction getMinimum () retourne l’élément minimum de la pile.

Par exemple: considérons l'exemple ci-dessous

 cas # 1 

 5 -> TOP 
 1 
 4 
 6 
 2 

 Lorsque getMinimum () est appelé, il devrait retourner 1 qui est l’élément minimum 
 dans la pile. 

 cas # 2 

 stack.pop () 
 stack.pop () 

 Remarque: 5 et 1 sortent tous deux de la pile. Ainsi, après cela, la pile 
 Ressemble à, 

 4 -> TOP 
 6 
 2 

 Lorsque getMinimum () est appelé, il devrait renvoyer 2 minimum dans la pile 
 .

Constriants:

  1. getMinimum devrait renvoyer la valeur minimale dans O (1)
  2. La contrainte d'espace doit également être prise en compte lors de la conception et si vous utilisez de l'espace supplémentaire, il doit être constant.
110
Ganesh M

EDIT: Cela échoue avec la contrainte "espace constant" - il double en gros l'espace requis. Je doute fort qu'il existe une solution qui ne le fasse pas, sans toutefois détruire la complexité de l'exécution à un moment donné (par exemple, créer Push/pop O (n)). Notez que cela ne change pas la complexité de l'espace requis, par exemple. Si vous avez une pile avec O(n) espace requis, il s'agira toujours de O(n) avec un facteur constant différent.

Solution à espace non constant

Conservez une pile "dupliquée" de "minimum de toutes les valeurs inférieures à la pile". Lorsque vous éjectez la pile principale, effacez également la pile minimale. Lorsque vous poussez la pile principale, poussez le nouvel élément ou le min en cours, selon la valeur la plus basse. getMinimum() est alors implémenté en tant que minStack.peek().

Donc, en utilisant votre exemple, nous aurions:

Real stack        Min stack

5  --> TOP        1
1                 1
4                 2
6                 2
2                 2

Après avoir sauté deux fois, vous obtenez:

Real stack        Min stack

4                 2
6                 2
2                 2

S'il vous plaît laissez-moi savoir si ce n'est pas assez d'informations. C'est simple quand vous le prenez, mais cela pourrait prendre un peu de casse-tête au début :)

(L’inconvénient, c’est bien sûr que cela double l’espace requis. Le temps d’exécution n’en souffre pas beaucoup, c’est-à-dire qu’il a toujours la même complexité.)

EDIT: Il y a une variation qui est un peu plus délicate, mais qui a une meilleure place en général. Nous avons toujours la pile min, mais nous n'en sortons que lorsque la valeur que nous extrayons de la pile principale est égale à celle de la pile min. Nous ne sommes que Push à la pile minimale lorsque la valeur insérée dans la pile principale est inférieure à ou égale à la valeur minimale actuelle. Cela permet de dupliquer les valeurs minimales. getMinimum() n’est encore qu’une opération à la légère. Par exemple, en prenant la version originale et en appuyant à nouveau sur 1, nous obtiendrions:

Real stack        Min stack

1  --> TOP        1
5                 1
1                 2
4                 
6                 
2                 

Sauter de ce qui précède apparaît des deux piles car 1 == 1, laissant:

Real stack        Min stack

5  --> TOP        1
1                 2
4                 
6                 
2                 

Découper à nouveau uniquement apparaît de la pile principale, car 5> 1:

Real stack        Min stack

1                 1
4                 2
6                 
2                 

Popping à nouveau fait apparaître les deux piles car 1 == 1:

Real stack        Min stack

4                 2
6                 
2                 

Cela aboutit à la même complexité d'espace dans le cas le plus défavorable (le double de la pile d'origine) mais à une utilisation d'espace bien meilleure si nous obtenons rarement un "nouveau minimum ou égal".

EDIT: Voici une mise en œuvre du schéma diabolique de Pete. Je ne l'ai pas testé à fond, mais je réfléchis ça va :)

using System.Collections.Generic;

public class FastMinStack<T>
{
    private readonly Stack<T> stack = new Stack<T>();
    // Could pass this in to the constructor
    private readonly IComparer<T> comparer = Comparer<T>.Default;

    private T currentMin;

    public T Minimum
    {
        get { return currentMin; }
    }

    public void Push(T element)
    {
        if (stack.Count == 0 ||
            comparer.Compare(element, currentMin) <= 0)
        {
            stack.Push(currentMin);
            stack.Push(element);
            currentMin = element;
        }
        else
        {
            stack.Push(element);
        }
    }

    public T Pop()
    {
        T ret = stack.Pop();
        if (comparer.Compare(ret, currentMin) == 0)
        {
            currentMin = stack.Pop();
        }
        return ret;
    }
}
169
Jon Skeet

Ajoutez un champ contenant la valeur minimale et mettez-le à jour pendant Pop () et Push (). De cette façon, getMinimum () sera O (1), mais Pop () et Push () devront faire un peu plus de travail. 

Si une valeur minimale est affichée, Pop () sera O (n), sinon ils seront toujours tous les deux O (1). Lorsque vous redimensionnez, Push () devient O(n) conformément à l'implémentation Stack.

Voici une mise en œuvre rapide

public sealed class MinStack {
    private int MinimumValue;
    private readonly Stack<int> Stack = new Stack<int>();

    public int GetMinimum() {
        if (IsEmpty) {
            throw new InvalidOperationException("Stack is empty");
        }
        return MinimumValue;
    }

    public int Pop() {
        var value = Stack.Pop();
        if (value == MinimumValue) {
            MinimumValue = Stack.Min();
        }
        return value;
    }

    public void Push(int value) {
        if (IsEmpty || value < MinimumValue) {
            MinimumValue = value;
        }
        Stack.Push(value);
    }

    private bool IsEmpty { get { return Stack.Count() == 0; } }
}
40
Brian Rasmussen
public class StackWithMin {
    int min;
    int size;
    int[] data = new int[1024];

    public void Push ( int val ) {
        if ( size == 0 ) {
            data[size] = val;
            min = val;
        } else if ( val < min) {
            data[size] = 2 * val - min;
            min = val;

            assert (data[size] < min); 
        } else {
            data[size] = val;
        }

        ++size;

        // check size and grow array
    }

    public int getMin () {
        return min;
    }

    public int pop () {
        --size;

        int val = data[size];

        if ( ( size > 0 ) && ( val < min ) ) {
            int prevMin = min;
            min += min - val;
            return prevMin;
        } else {
            return val;
        }
    }

    public boolean isEmpty () {
        return size == 0;
    }

    public static void main (String...args) {
        StackWithMin stack = new StackWithMin();

        for ( String arg: args ) 
            stack.Push( Integer.parseInt( arg ) );

        while ( ! stack.isEmpty() ) {
            int min = stack.getMin();
            int val = stack.pop();

            System.out.println( val + " " + min );
        }

        System.out.println();
    }

}

Il stocke explicitement le minimum actuel, et si le minimum change, au lieu d’appuyer sur la valeur, il applique une valeur identique à l’autre côté du nouveau minimum (si min = 7 et que vous appuyez sur 5, il en applique 3 | 7-5 | = 3) et met min à 5; si vous passez 3 alors que min est 5, la valeur affichée est inférieure à min, donc inverse la procédure pour obtenir 7 pour le nouveau min, puis renvoie la valeur précédente. min). Comme toute valeur qui ne provoque pas de modification du minimum actuel est supérieure au minimum actuel, vous disposez de quelque chose qui peut être utilisé pour différencier les valeurs qui modifient le minimum des autres.

Dans les langues qui utilisent des entiers de taille fixe, vous empruntez un peu d’espace dans la représentation des valeurs, ce qui risque de provoquer un débordement et l’assertion d’échec. Mais sinon, c'est un espace supplémentaire constant et toutes les opérations sont toujours O (1).

Les piles basées sur des listes chaînées ont d'autres emplacements sur lesquels vous pouvez emprunter un bit, par exemple en C le bit le moins significatif du pointeur suivant ou en Java le type des objets de la liste chaînée. Pour Java, cela signifie plus d'espace utilisé par rapport à une pile contiguë, car vous avez la surcharge d'objet par lien:

public class LinkedStackWithMin {
    private static class Link {
        final int value;
        final Link next;

        Link ( int value, Link next ) {
            this.value = value;
            this.next = next;
        }

        int pop ( LinkedStackWithMin stack ) {
            stack.top = next;
            return value;
        }
    }

    private static class MinLink extends Link {
        MinLink ( int value, Link next ) {
            super( value, next );
        }

        int pop ( LinkedStackWithMin stack ) {
            stack.top = next;
            int prevMin = stack.min;
            stack.min = value;
            return prevMin;
        }
    }

    Link top;
    int min;

    public LinkedStackWithMin () {
    }

    public void Push ( int val ) {
        if ( ( top == null ) || ( val < min ) ) {
            top = new MinLink(min, top);
            min = val;
        } else {
            top = new Link(val, top);
        }
    }

    public int pop () {
        return top.pop(this);
    }

    public int getMin () {
        return min;
    }

    public boolean isEmpty () {
        return top == null;
    }

En C, les frais généraux n'existent pas et vous pouvez emprunter le lsb du pointeur suivant:

typedef struct _stack_link stack_with_min;

typedef struct _stack_link stack_link;

struct _stack_link {
    size_t  next;
    int     value;
};

stack_link* get_next ( stack_link* link ) 
{
    return ( stack_link * )( link -> next & ~ ( size_t ) 1 );
}

bool is_min ( stack_link* link )
{
    return ( link -> next & 1 ) ! = 0;
}

void Push ( stack_with_min* stack, int value )
{
    stack_link *link = malloc ( sizeof( stack_link ) );

    link -> next = ( size_t ) stack -> next;

    if ( (stack -> next == 0) || ( value == stack -> value ) ) {
        link -> value = stack -> value;
        link -> next |= 1; // mark as min
    } else {
        link -> value = value;
    }

    stack -> next = link;
}

etc.;

Cependant, aucun d'entre eux n'est vraiment O (1). En pratique, ils ne nécessitent plus d'espace, car ils exploitent des trous dans les représentations de nombres, d'objets ou de pointeurs dans ces langages. Mais une machine théorique qui utilisait une représentation plus compacte aurait besoin d'ajouter un bit supplémentaire à cette représentation dans chaque cas. 

16
Pete Kirkham

J'ai trouvé une solution qui satisfait toutes les contraintes mentionnées (opérations à temps constant) et espace supplémentaire constant.

L'idée est de stocker la différence entre la valeur minimale et le nombre saisi et de mettre à jour la valeur minimale si ce n'est plus le minimum.

Le code est comme suit:

public class MinStack {
    long min;
    Stack<Long> stack;

    public MinStack(){
        stack = new Stack<>();
    }

    public void Push(int x) {
        if (stack.isEmpty()) {
            stack.Push(0L);
            min = x;
        } else {
            stack.Push(x - min); //Could be negative if min value needs to change
            if (x < min) min = x;
        }
    }

    public int pop() {
        if (stack.isEmpty()) return;

        long pop = stack.pop();

        if (pop < 0) {
            long ret = min
            min = min - pop; //If negative, increase the min value
            return (int)ret;
        }
        return (int)(pop + min);

    }

    public int top() {
        long top = stack.peek();
        if (top < 0) {
            return (int)min;
        } else {
           return (int)(top + min);
        }
    }

    public int getMin() {
        return (int)min;
    }
}

Le crédit va à: https://leetcode.com/discuss/15679/share-my-Java-solution-with-only-one-stack

12
WoLfPwNeR

Quelles sont les contraintes d’exécution de Push et pop? S'il n'est pas nécessaire qu'ils soient constants, calculez simplement la valeur minimale dans ces deux opérations (en les rendantO( n )). Sinon, je ne vois pas comment cela peut être fait avec un espace supplémentaire constant.

7
Konrad Rudolph

Je poste le code complet ici pour trouver min et max dans une pile donnée.

La complexité temporelle sera O (1) ..

package com.Java.util.collection.advance.datastructure;

/**
 * 
 * @author vsinha
 *
 */
public abstract interface Stack<E> {

    /**
     * Placing a data item on the top of the stack is called pushing it
     * @param element
     * 
     */
    public abstract void Push(E element);


    /**
     * Removing it from the top of the stack is called popping it
     * @return the top element
     */
    public abstract E pop();

    /**
     * Get it top element from the stack and it 
     * but the item is not removed from the stack, which remains unchanged
     * @return the top element
     */
    public abstract E peek();

    /**
     * Get the current size of the stack.
     * @return
     */
    public abstract int size();


    /**
     * Check whether stack is empty of not.
     * @return true if stack is empty, false if stack is not empty
     */
    public abstract boolean empty();



}



package com.Java.util.collection.advance.datastructure;

@SuppressWarnings("hiding")
public abstract interface MinMaxStack<Integer> extends Stack<Integer> {

    public abstract int min();

    public abstract int max();

}


package com.Java.util.collection.advance.datastructure;

import Java.util.Arrays;

/**
 * 
 * @author vsinha
 *
 * @param <E>
 */
public class MyStack<E> implements Stack<E> {

    private E[] elements =null;
    private int size = 0;
    private int top = -1;
    private final static int DEFAULT_INTIAL_CAPACITY = 10;


    public MyStack(){
        // If you don't specify the size of stack. By default, Stack size will be 10
        this(DEFAULT_INTIAL_CAPACITY);
    }

    @SuppressWarnings("unchecked")
    public MyStack(int intialCapacity){
        if(intialCapacity <=0){
            throw new IllegalArgumentException("initial capacity can't be negative or zero");
        }
        // Can't create generic type array
        elements =(E[]) new Object[intialCapacity];
    }

    @Override
    public void Push(E element) {
        ensureCapacity();
        elements[++top] = element;
        ++size;
    }

    @Override
    public E pop() {
        E element = null;
        if(!empty()) {
            element=elements[top];
            // Nullify the reference
            elements[top] =null;
            --top;
            --size;
        }
        return element;
    }

    @Override
    public E peek() {
        E element = null;
        if(!empty()) {
            element=elements[top];
        }
        return element;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean empty() {
        return size == 0;
    }

    /**
     * Increases the capacity of this <tt>Stack by double of its current length</tt> instance, 
     * if stack is full 
     */
    private void ensureCapacity() {
        if(size != elements.length) {
            // Don't do anything. Stack has space.
        } else{
            elements = Arrays.copyOf(elements, size *2);
        }
    }

    @Override
    public String toString() {
        return "MyStack [elements=" + Arrays.toString(elements) + ", size="
                + size + ", top=" + top + "]";
    }


}


package com.Java.util.collection.advance.datastructure;

/**
 * Time complexity will be O(1) to find min and max in a given stack.
 * @author vsinha
 *
 */
public class MinMaxStackFinder extends MyStack<Integer> implements MinMaxStack<Integer> {

    private MyStack<Integer> minStack;

    private MyStack<Integer> maxStack;

    public MinMaxStackFinder (int intialCapacity){
        super(intialCapacity);
        minStack =new MyStack<Integer>();
        maxStack =new MyStack<Integer>();

    }
    public void Push(Integer element) {
        // Current element is lesser or equal than min() value, Push the current element in min stack also.
        if(!minStack.empty()) {
            if(min() >= element) {
                minStack.Push(element);
            }
        } else{
            minStack.Push(element);
        }
        // Current element is greater or equal than max() value, Push the current element in max stack also.
        if(!maxStack.empty()) {
            if(max() <= element) {
                maxStack.Push(element);
            }
        } else{
            maxStack.Push(element);
        }
        super.Push(element);
    }


    public Integer pop(){
        Integer curr = super.pop();
        if(curr !=null) {
            if(min() == curr) {
                minStack.pop();
            } 

            if(max() == curr){
                maxStack.pop();
            }
        }
        return curr;
    }


    @Override
    public int min() {
        return minStack.peek();
    }

    @Override
    public int max() {
        return maxStack.peek();
    }


    @Override
    public String toString() {
        return super.toString()+"\nMinMaxStackFinder [minStack=" + minStack + "\n maxStack="
                + maxStack + "]" ;
    }




}

// You can use the below program to execute it.

package com.Java.util.collection.advance.datastructure;

import Java.util.Random;

public class MinMaxStackFinderApp {

    public static void main(String[] args) {
        MinMaxStack<Integer> stack =new MinMaxStackFinder(10);
        Random random =new Random();
        for(int i =0; i< 10; i++){
            stack.Push(random.nextInt(100));
        }
        System.out.println(stack);
        System.out.println("MAX :"+stack.max());
        System.out.println("MIN :"+stack.min());

        stack.pop();
        stack.pop();
        stack.pop();
        stack.pop();
        stack.pop();

        System.out.println(stack);
        System.out.println("MAX :"+stack.max());
        System.out.println("MIN :"+stack.min());
    }
}

Faites-moi savoir si vous êtes confronté à un problème 

Merci, Vikash 

1
java baby

Vous pouvez étendre votre classe de pile d'origine et lui ajouter simplement le suivi minimal. Laissez la classe parent d'origine gérer tout le reste comme d'habitude.

public class StackWithMin extends Stack<Integer> {  

    private Stack<Integer> min;

    public StackWithMin() {
        min = new Stack<>();
    }

    public void Push(int num) {
        if (super.isEmpty()) {
            min.Push(num);
        } else if (num <= min.peek()) {
            min.Push(num);
        }
        super.Push(num);
    }

    public int min() {
        return min.peek();
    }

    public Integer pop() {
        if (super.peek() == min.peek()) {
            min.pop();
        }
        return super.pop();
    }   
}
1
Arcturus

J'ai utilisé un autre type de pile. Voici la mise en œuvre.

//
//  main.cpp
//  Eighth
//
//  Created by chaitanya on 4/11/13.
//  Copyright (c) 2013 cbilgika. All rights reserved.
//

#include <iostream>
#include <limits>
using namespace std;
struct stack
{
    int num;
    int minnum;
}a[100];

void Push(int n,int m,int &top)
{

    top++;
    if (top>=100) {
        cout<<"Stack Full";
        cout<<endl;
    }
    else{
        a[top].num = n;
        a[top].minnum = m;
    }


}

void pop(int &top)
{
    if (top<0) {
        cout<<"Stack Empty";
        cout<<endl;
    }
    else{
       top--; 
    }


}
void print(int &top)
{
    cout<<"Stack: "<<endl;
    for (int j = 0; j<=top ; j++) {
        cout<<"("<<a[j].num<<","<<a[j].minnum<<")"<<endl;
    }
}


void get_min(int &top)
{
    if (top < 0)
    {
        cout<<"Empty Stack";
    }
    else{
        cout<<"Minimum element is: "<<a[top].minnum;
    }
    cout<<endl;
}

int main()
{

    int top = -1,min = numeric_limits<int>::min(),num;
    cout<<"Enter the list to Push (-1 to stop): ";
    cin>>num;
    while (num!=-1) {
        if (top == -1) {
            min = num;
            Push(num, min, top);
        }
        else{
            if (num < min) {
                min = num;
            }
            Push(num, min, top);
        }
        cin>>num;
    }
    print(top);
    get_min(top);
    return 0;
}

Sortie:

Enter the list to Push (-1 to stop): 5
1
4
6
2
-1
Stack: 
(5,5)
(1,1)
(4,1)
(6,1)
(2,1)
Minimum element is: 1

Essayez-le Je pense que cela répond à la question. Le deuxième élément de chaque paire donne la valeur minimale vue lors de l'insertion de cet élément.

1
Chaitanya Bilgikar

Voici ma solution en Java en utilisant la liste chaînée.

class Stack{
    int min;
    Node top;
    static class Node{
        private int data;
        private Node next;
        private int min;

        Node(int data, int min){
           this.data = data;
           this.min = min;
           this.next = null; 
    }
}

  void Push(int data){
        Node temp;
        if(top == null){
            temp = new Node(data,data);
            top = temp;
            top.min = data;
        }
        if(top.min > data){
            temp = new Node(data,data);
            temp.next = top;
            top = temp;
        } else {
            temp = new Node(data, top.min);
            temp.next = top;
            top = temp;
        }
  }

  void pop(){
    if(top != null){
        top = top.next;
    }
  }

  int min(){
    return top.min;
  }

}

1
Irshad ck

Voici mon code qui fonctionne avec O (1). Le code précédent que j'avais posté avait un problème lorsque l'élément minimum est sauté. J'ai modifié mon code. Celui-ci utilise une autre pile qui maintient l'élément minimum présent dans la pile au-dessus de l'élément poussé actuel. 

 class StackDemo
{
    int[] stk = new int[100];
    int top;
    public StackDemo()
    {
        top = -1;
    }
    public void Push(int value)
    {
        if (top == 100)
            Console.WriteLine("Stack Overflow");
        else
            stk[++top] = value;
    }
    public bool IsEmpty()
    {
        if (top == -1)
            return true;
        else
            return false;
    }
    public int Pop()
    {
        if (IsEmpty())
        {
            Console.WriteLine("Stack Underflow");
            return 0;
        }
        else
            return stk[top--];
    }
    public void Display()
    {
        for (int i = top; i >= 0; i--)
            Console.WriteLine(stk[i]);
    }
}
class MinStack : StackDemo
{
    int top;
    int[] stack = new int[100];
    StackDemo s1; int min;
    public MinStack()
    {
        top = -1;
        s1 = new StackDemo();
    }
    public void PushElement(int value)
    {
        s1.Push(value);
        if (top == 100)
            Console.WriteLine("Stack Overflow");
        if (top == -1)
        {
            stack[++top] = value;
            stack[++top] = value;   
        }
        else
        {
            //  stack[++top]=value;
            int ele = PopElement();
            stack[++top] = ele;
            int a = MininmumElement(min, value);
              stack[++top] = min;

                stack[++top] = value;
                stack[++top] = a;


        }
    }
    public int PopElement()
    {

        if (top == -1)
            return 1000;
        else
        {
            min = stack[top--];
            return stack[top--];
        }

    }
    public int PopfromStack()
    {
        if (top == -1)
            return 1000;
        else
        {
            s1.Pop();
            return PopElement();
        }
    }
    public int MininmumElement(int a,int b)
    {
        if (a > b)
            return b;
        else
            return a;
    }
    public int StackTop()
    {
        return stack[top];
    }
    public void DisplayMinStack()
    {
        for (int i = top; i >= 0; i--)
            Console.WriteLine(stack[i]);
    }
}
class Program
{
    static void Main(string[] args)
    {
        MinStack ms = new MinStack();
        ms.PushElement(15);
        ms.PushElement(2);
        ms.PushElement(1);
        ms.PushElement(13);
        ms.PushElement(5);
        ms.PushElement(21);
        Console.WriteLine("Min Stack");
        ms.DisplayMinStack();
        Console.WriteLine("Minimum Element:"+ms.StackTop());
        ms.PopfromStack();
        ms.PopfromStack();
        ms.PopfromStack();
        ms.PopfromStack();

        Console.WriteLine("Min Stack");
        ms.DisplayMinStack();
        Console.WriteLine("Minimum Element:" + ms.StackTop());
        Thread.Sleep(1000000);
    }
}
1
Akshay
class FastStack {

    private static class StackNode {
        private Integer data;
        private StackNode nextMin;

        public StackNode(Integer data) {
            this.data = data;
        }

        public Integer getData() {
            return data;
        }

        public void setData(Integer data) {
            this.data = data;
        }

        public StackNode getNextMin() {
            return nextMin;
        }

        public void setNextMin(StackNode nextMin) {
            this.nextMin = nextMin;
        }

    }

    private LinkedList<StackNode> stack = new LinkedList<>();

    private StackNode currentMin = null;

    public void Push(Integer item) {
        StackNode node = new StackNode(item);
        if (currentMin == null) {
            currentMin = node;
            node.setNextMin(null);
        } else if (item < currentMin.getData()) {
            StackNode oldMinNode = currentMin;
            node.setNextMin(oldMinNode);
            currentMin = node;
        }

        stack.addFirst(node);
    }

    public Integer pop() {
        if (stack.isEmpty()) {
            throw new EmptyStackException();
        }
        StackNode node = stack.peek();
        if (currentMin == node) {
            currentMin = node.getNextMin();
        }
        stack.removeFirst();
        return node.getData();
    }

    public Integer getMinimum() {
        if (stack.isEmpty()) {
            throw new NoSuchElementException("Stack is empty");
        }
        return currentMin.getData();
    }
}
0

Voici l'implémentation PHP de ce qui a été expliqué dans La réponse de Jon Skeet en tant qu'implémentation légèrement plus complexe de la complexité de l'espace pour obtenir le maximum de pile dans O (1). 

<?php

/**
 * An ordinary stack implementation.
 *
 * In real life we could just extend the built-in "SplStack" class.
 */
class BaseIntegerStack
{
    /**
     * Stack main storage.
     *
     * @var array
     */
    private $storage = [];

    // ------------------------------------------------------------------------
    // Public API
    // ------------------------------------------------------------------------

    /**
     * Pushes to stack.
     *
     * @param  int $value New item.
     *
     * @return bool
     */
    public function Push($value)
    {
        return is_integer($value)
            ? (bool) array_Push($this->storage, $value)
            : false;
    }

    /**
     * Pops an element off the stack.
     *
     * @return int
     */
    public function pop()
    {
        return array_pop($this->storage);
    }

    /**
     * See what's on top of the stack.
     *
     * @return int|bool
     */
    public function top()
    {
        return empty($this->storage)
            ? false
            : end($this->storage);
    }

    // ------------------------------------------------------------------------
    // Magic methods
    // ------------------------------------------------------------------------

    /**
     * String representation of the stack.
     *
     * @return string
     */
    public function __toString()
    {
        return implode('|', $this->storage);
    }
} // End of BaseIntegerStack class

/**
 * The stack implementation with getMax() method in O(1).
 */
class Stack extends BaseIntegerStack
{
    /**
     * Internal stack to keep track of main stack max values.
     *
     * @var BaseIntegerStack
     */
    private $maxStack;

    /**
     * Stack class constructor.
     *
     * Dependencies are injected.
     *
     * @param BaseIntegerStack $stack Internal stack.
     *
     * @return void
     */
    public function __construct(BaseIntegerStack $stack)
    {
        $this->maxStack = $stack;
    }

    // ------------------------------------------------------------------------
    // Public API
    // ------------------------------------------------------------------------

    /**
     * Prepends an item into the stack maintaining max values.
     *
     * @param  int $value New item to Push to the stack.
     *
     * @return bool
     */
    public function Push($value)
    {
        if ($this->isNewMax($value)) {
            $this->maxStack->Push($value);
        }

        parent::Push($value);
    }

    /**
     * Pops an element off the stack maintaining max values.
     *
     * @return int
     */
    public function pop()
    {
        $popped = parent::pop();

        if ($popped == $this->maxStack->top()) {
            $this->maxStack->pop();
        }

        return $popped;
    }

    /**
     * Finds the maximum of stack in O(1).
     *
     * @return int
     * @see Push()
     */
    public function getMax()
    {
        return $this->maxStack->top();
    }

    // ------------------------------------------------------------------------
    // Internal helpers
    // ------------------------------------------------------------------------

    /**
     * Checks that passing value is a new stack max or not.
     *
     * @param  int $new New integer to check.
     *
     * @return boolean
     */
    private function isNewMax($new)
    {
        return empty($this->maxStack) OR $new > $this->maxStack->top();
    }

} // End of Stack class

// ------------------------------------------------------------------------
// Stack Consumption and Test
// ------------------------------------------------------------------------
$stack = new Stack(
    new BaseIntegerStack
);

$stack->Push(9);
$stack->Push(4);
$stack->Push(237);
$stack->Push(5);
$stack->Push(556);
$stack->Push(15);

print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n\n";

print "Pop: {$stack->pop()}\n";
print "Pop: {$stack->pop()}\n\n";

print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n\n";

print "Pop: {$stack->pop()}\n";
print "Pop: {$stack->pop()}\n\n";

print "Stack: $stack\n";
print "Max: {$stack->getMax()}\n";

// Here's the sample output:
//
// Stack: 9|4|237|5|556|15
// Max: 556
//
// Pop: 15
// Pop: 556
//
// Stack: 9|4|237|5
// Max: 237
//
// Pop: 5
// Pop: 237
//
// Stack: 9|4
// Max: 9
0
sepehr

Nous pouvons faisons cela dans O(n) et la complexité d'espace O(1), comme suit:

class MinStackOptimized:
  def __init__(self):
      self.stack = []
      self.min = None

  def Push(self, x): 
      if not self.stack:
          # stack is empty therefore directly add
          self.stack.append(x)
          self.min = x 
      else:
          """
          Directly add (x-self.min) to the stack. This also ensures anytime we have a 
          negative number on the stack is when x was less than existing minimum
          recorded thus far.
          """
          self.stack.append(x-self.min)
          if x < self.min:
              # Update x to new min
              self.min = x 

  def pop(self):
      x = self.stack.pop()
      if x < 0:
          """ 
          if popped element was negative therefore this was the minimum
          element, whose actual value is in self.min but stored value is what
          contributes to get the next min. (this is one of the trick we use to ensure
          we are able to get old minimum once current minimum gets popped proof is given
          below in pop method), value stored during Push was:
          (x - self.old_min) and self.min = x therefore we need to backtrack
          these steps self.min(current) - stack_value(x) actually implies to
              x (self.min) - (x - self.old_min)
          which therefore gives old_min back and therefore can now be set
          back as current self.min.
          """
          self.min = self.min - x 

  def top(self):
      x = self.stack[-1]
      if x < 0:
          """ 
          As discussed above anytime there is a negative value on stack, this
          is the min value so far and therefore actual value is in self.min,
          current stack value is just for getting the next min at the time
          this gets popped.
          """
          return self.min
      else:
          """ 
          if top element of the stack was positive then it's simple, it was
          not the minimum at the time of pushing it and therefore what we did
          was x(actual) - self.min(min element at current stage) let's say `y`
          therefore we just need to reverse the process to get the actual
          value. Therefore self.min + y, which would translate to
              self.min + x(actual) - self.min, thereby giving x(actual) back
          as desired.
          """
          return x + self.min

  def getMin(self):
      # Always self.min variable holds the minimum so for so easy peezy.
      return self.min
0
AnukuL
    **The task can be acheived by creating two stacks:**



import Java.util.Stack;
    /*
     * 
     * Find min in stack using O(n) Space Complexity
     */
    public class DeleteMinFromStack {

        void createStack(Stack<Integer> primary, Stack<Integer> minStack, int[] arr) {
    /* Create main Stack and in parallel create the stack which contains the minimum seen so far while creating main Stack */
            primary.Push(arr[0]);
            minStack.Push(arr[0]);

            for (int i = 1; i < arr.length; i++) {
                primary.Push(arr[i]);
                if (arr[i] <= minStack.peek())// Condition to check to Push the value in minimum stack only when this urrent value is less than value seen at top of this stack */
                    minStack.Push(arr[i]);
            }

        }

        int findMin(Stack<Integer> secStack) {
            return secStack.peek();
        }

        public static void main(String args[]) {

            Stack<Integer> primaryStack = new Stack<Integer>();
            Stack<Integer> minStack = new Stack<Integer>();

            DeleteMinFromStack deleteMinFromStack = new DeleteMinFromStack();

            int[] arr = { 5, 5, 6, 8, 13, 1, 11, 6, 12 };
            deleteMinFromStack.createStack(primaryStack, minStack, arr);
            int mimElement = deleteMinFromStack.findMin(primaryStack, minStack);
    /** This check for algorithm when the main Stack Shrinks by size say i as in loop below */
            for (int i = 0; i < 2; i++) {
                primaryStack.pop();
            }

            System.out.println(" Minimum element is " + mimElement);
        }

    }
/*
here in have tried to add for loop wherin the main tack can be shrinked/expaned so we can check the algorithm */
0
Akhil Gupta

Je pense que vous pouvez simplement utiliser une LinkedList dans votre implémentation de pile.

La première fois que vous transmettez une valeur, vous mettez cette valeur en tête de la liste liée.

puis chaque fois que vous appuyez sur une valeur, si la nouvelle valeur <head.data, effectuez une opération prepand (ce qui signifie que la tête devient la nouvelle valeur)

sinon, effectuez une opération d'ajout.

Lorsque vous faites un pop (), vous vérifiez si min == linkedlist.head.data, si oui, alors head = head.next;

Voici mon code.

public class Stack {

int[] elements;
int top;
Linkedlists min;

public Stack(int n) {
    elements = new int[n];
    top = 0;
    min = new Linkedlists();
}

public void realloc(int n) {
    int[] tab = new int[n];
    for (int i = 0; i < top; i++) {
        tab[i] = elements[i];
    }

    elements = tab;
}

public void Push(int x) {
    if (top == elements.length) {
        realloc(elements.length * 2);
    }
    if (top == 0) {
        min.pre(x);
    } else if (x < min.head.data) {
        min.pre(x);
    } else {
        min.app(x);
    }
    elements[top++] = x;
}

public int pop() {

    int x = elements[--top];
    if (top == 0) {

    }
    if (this.getMin() == x) {
        min.head = min.head.next;
    }
    elements[top] = 0;
    if (4 * top < elements.length) {
        realloc((elements.length + 1) / 2);
    }

    return x;
}

public void display() {
    for (Object x : elements) {
        System.out.print(x + " ");
    }

}

public int getMin() {
    if (top == 0) {
        return 0;
    }
    return this.min.head.data;
}

public static void main(String[] args) {
    Stack stack = new Stack(4);
    stack.Push(2);
    stack.Push(3);
    stack.Push(1);
    stack.Push(4);
    stack.Push(5);
    stack.pop();
    stack.pop();
    stack.pop();
    stack.Push(1);
    stack.pop();
    stack.pop();
    stack.pop();
    stack.Push(2);
    System.out.println(stack.getMin());
    stack.display();

}

 }
0
Zok

Voici l'implémentation C++ de Jon Skeets Answer . Ce n'est peut-être pas la meilleure façon de l'implémenter, mais il fait exactement ce qu'il est censé faire.

class Stack {
private:
    struct stack_node {
        int val;
        stack_node *next;
    };
    stack_node *top;
    stack_node *min_top;
public:
    Stack() {
        top = nullptr;
        min_top = nullptr;
    }    
    void Push(int num) {
        stack_node *new_node = nullptr;
        new_node = new stack_node;
        new_node->val = num;

        if (is_empty()) {
            top = new_node;
            new_node->next = nullptr;

            min_top = new_node;
            new_node->next = nullptr;
        } else {
            new_node->next = top;
            top = new_node;

            if (new_node->val <= min_top->val) {
                new_node->next = min_top;
                min_top = new_node;
            }
        }
    }

    void pop(int &num) {
        stack_node *tmp_node = nullptr;
        stack_node *min_tmp = nullptr;

        if (is_empty()) {
            std::cout << "It's empty\n";
        } else {
            num = top->val;
            if (top->val == min_top->val) {
                min_tmp = min_top->next;
                delete min_top;
                min_top = min_tmp;
            }
            tmp_node = top->next;
            delete top;
            top = tmp_node;
        }
    }

    bool is_empty() const {
        return !top;
    }

    void get_min(int &item) {
        item = min_top->val;
    }
};

Et voici le pilote pour la classe

int main() {
    int pop, min_el;
    Stack my_stack;

    my_stack.Push(4);
    my_stack.Push(6);
    my_stack.Push(88);
    my_stack.Push(1);
    my_stack.Push(234);
    my_stack.Push(2);

    my_stack.get_min(min_el);
    cout << "Min: " << min_el << endl;

    my_stack.pop(pop);
    cout << "Popped stock element: " << pop << endl;

    my_stack.pop(pop);
    cout << "Popped stock element: " << pop << endl;

    my_stack.pop(pop);
    cout << "Popped stock element: " << pop << endl;

    my_stack.get_min(min_el);
    cout << "Min: " << min_el << endl;

    return 0;
}

Sortie:

Min: 1
Popped stock element: 2
Popped stock element: 234
Popped stock element: 1
Min: 4
0
NikaTsanka

J'ai trouvé cette solution ici

struct StackGetMin {
  void Push(int x) {
    elements.Push(x);
    if (minStack.empty() || x <= minStack.top())
      minStack.Push(x);
  }
  bool pop() {
    if (elements.empty()) return false;
    if (elements.top() == minStack.top())
      minStack.pop();
    elements.pop();
    return true;
  }
  bool getMin(int &min) {
    if (minStack.empty()) {
      return false;
    } else {
      min = minStack.top();
      return true;
    }
  }
  stack<int> elements;
  stack<int> minStack;
};
0
isxaker

Voici mon code qui fonctionne avec O (1). Ici, j'ai utilisé une paire de vecteurs qui contient la valeur qui a poussé et qui contient aussi la valeur minimale jusqu'à cette valeur.


Voici ma version de l'implémentation C++.

vector<pair<int,int> >A;
int sz=0; // to keep track of the size of vector

class MinStack
{
public:
    MinStack()
    {
        A.clear();
        sz=0;
    }

    void Push(int x)
    {
        int mn=(sz==0)?x: min(A[sz-1].second,x); //find the minimum value upto this pushed value
        A.Push_back(make_pair(x,mn));
        sz++; // increment the size
    }

    void pop()
    {
        if(sz==0) return;
        A.pop_back(); // pop the last inserted element
        sz--;  // decrement size
    }

    int top()
    {
        if(sz==0)   return -1;  // if stack empty return -1
        return A[sz-1].first;  // return the top element
    }

    int getMin()
    {
        if(sz==0) return -1;
        return A[sz-1].second; // return the minimum value at sz-1 
    }
};
0
akid
 class MyStackImplementation{
private final int capacity = 4;
int min;
int arr[] = new int[capacity];
int top = -1;

public void Push ( int val ) {
top++;
if(top <= capacity-1){
    if(top == 0){
min = val;
arr[top] = val;
}
else if(val < min){
arr[top] = arr[top]+min;
min = arr[top]-min;
arr[top] = arr[top]-min;
}
else {
arr[top] = val;
}
System.out.println("element is pushed");
}
else System.out.println("stack is full");

}

 public void pop () {
top--;
   if(top > -1){ 

   min = arr[top];
}
else {min=0; System.out.println("stack is under flow");}

}
public int min(){
return min;
}

 public boolean isEmpty () {
    return top == 0;
}

public static void main(String...s){
MyStackImplementation msi = new MyStackImplementation();
msi.Push(1);
msi.Push(4);
msi.Push(2);
msi.Push(10);
System.out.println(msi.min);
msi.pop();
msi.pop();
msi.pop();
msi.pop();
msi.pop();
System.out.println(msi.min);

}
}
0
mayank
public class MinStack<E>{

    private final LinkedList<E> mainStack = new LinkedList<E>();
    private final LinkedList<E> minStack = new LinkedList<E>();
    private final Comparator<E> comparator;

    public MinStack(Comparator<E> comparator) 
    {
        this.comparator = comparator;
    }

    /**
     * Pushes an element onto the stack.
     *
     *
     * @param e the element to Push
     */
    public void Push(E e) {
        mainStack.Push(e);
        if(minStack.isEmpty())
        {
            minStack.Push(e);
        }
        else if(comparator.compare(e, minStack.peek())<=0)
        {
            minStack.Push(e);
        }
        else
        {
            minStack.Push(minStack.peek());
        }
    }

    /**
     * Pops an element from the stack.
     *
     *
     * @throws NoSuchElementException if this stack is empty
     */
    public E pop() {
       minStack.pop();
       return  mainStack.pop();
    }

    /**
     * Returns but not remove smallest element from the stack. Return null if stack is empty.
     *
     */
    public E getMinimum()
    {
        return minStack.peek();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Main stack{");
        for (E e : mainStack) {         
            sb.append(e.toString()).append(",");
        }
        sb.append("}");

        sb.append(" Min stack{");
        for (E e : minStack) {          
            sb.append(e.toString()).append(",");
        }
        sb.append("}");

        sb.append(" Minimum = ").append(getMinimum());
        return sb.toString();
    }

    public static void main(String[] args) {
        MinStack<Integer> st = new MinStack<Integer>(Comparators.INTEGERS);

        st.Push(2);
        Assert.assertTrue("2 is min in stack {2}", st.getMinimum().equals(2));
        System.out.println(st);

        st.Push(6);
        Assert.assertTrue("2 is min in stack {2,6}", st.getMinimum().equals(2));
        System.out.println(st);

        st.Push(4);
        Assert.assertTrue("2 is min in stack {2,6,4}", st.getMinimum().equals(2));
        System.out.println(st);

        st.Push(1);
        Assert.assertTrue("1 is min in stack {2,6,4,1}", st.getMinimum().equals(1));
        System.out.println(st);

        st.Push(5);
        Assert.assertTrue("1 is min in stack {2,6,4,1,5}", st.getMinimum().equals(1));
        System.out.println(st);

        st.pop();
        Assert.assertTrue("1 is min in stack {2,6,4,1}", st.getMinimum().equals(1));
        System.out.println(st);

        st.pop();
        Assert.assertTrue("2 is min in stack {2,6,4}", st.getMinimum().equals(2));
        System.out.println(st);

        st.pop();
        Assert.assertTrue("2 is min in stack {2,6}", st.getMinimum().equals(2));
        System.out.println(st);

        st.pop();
        Assert.assertTrue("2 is min in stack {2}", st.getMinimum().equals(2));
        System.out.println(st);

        st.pop();
        Assert.assertTrue("null is min in stack {}", st.getMinimum()==null);
        System.out.println(st);
    }
}
0
Nitin Taur
#include<stdio.h>
struct stack
{
    int data;
    int mindata;
}a[100];

void Push(int *tos,int input)
{
    if (*tos > 100)
    {
        printf("overflow");
        return;
    }
    (*tos)++;
    a[(*tos)].data=input;
    if (0 == *tos)
        a[*tos].mindata=input;
    else if (a[*tos -1].mindata < input)
        a[*tos].mindata=a[*tos -1].mindata;
    else
        a[*tos].mindata=input;
}

int pop(int * tos)
{
    if (*tos <= -1)
    {
        printf("underflow");
        return -1;
    }
    return(a[(*tos)--].data);
}
void display(int tos)
{
    while (tos > -1)
    {
        printf("%d:%d\t",a[tos].data,a[tos].mindata);
        tos--;
    }    
}

int min(int tos)
{
   return(a[tos].mindata);
}
int main()
{
int tos=-1,x,choice;
while(1)
{
    printf("press 1-Push,2-pop,3-mindata,4-display,5-exit ");
    scanf("%d",&choice);
    switch(choice)
    {
    case 1: printf("enter data to Push");
            scanf("%d",&x);
            Push(&tos,x);
            break;
    case 2: printf("the poped out data=%d ",pop(&tos));
            break;
    case 3: printf("The min peeped data:%d",min(tos));
            break;
    case 4: printf("The elements of stack \n");
            display(tos);
            break;
    default: exit(0);
}
}
0
tauqir azam

Voici ma version de mise en oeuvre. 

 struct MyStack {
 int element; 
 int * CurrentMiniAddress; 
 }; 

 void Push (valeur int) 
 {
 // Crée ta structure et remplis la valeur 
 MyStack S = new MyStack (); 
 S-> élément = valeur; 

 si (Stack.Empty ()) 
 {
 // La pile étant vide, pointez CurrentMiniAddress sur elle-même 
 S-> CurrentMiniAddress = S; 

 } 
 autre
 {
 // La pile n'est pas vide 

 // Récupère l'élément top. Pas de Pop () 
 MyStack * TopElement = Stack.Top (); 

 // Rappelez-vous toujours que l'élément TOP pointe vers le 
 // élément minimum dans la pile entière 
 si (S-> élément CurrentMiniAddress-> element) 
 {
 // Si la valeur actuelle est la valeur minimale dans toute la pile 
 // alors S pointe sur lui-même 
 S-> CurrentMiniAddress = S; 
 } 
 autre
 {
 // Donc ce n'est pas le minimum dans toute la pile 
 // Pas de soucis, TOP contient l'élément minimum 
 S-> CurrentMiniAddress = TopElement-> CurrentMiniAddress; 
 } 

 } 
 Stack.Add (S); 
 } 

 vide Pop () 
 {
 si (! Stack.Empty ()) 
 {
 Stack.Pop (); 
 } 
 } 

 int GetMinimum (Stack & stack) 
 {
 si (! stack.Empty ()) 
 {
 MyStack * Top = stack.top (); 
 // Top pointe toujours sur le minimumx 
 return Top-> CurrentMiniAddress-> element; 
 } 
 } 
0
Ganesh M

Pour obtenir des éléments Min de Stack. Nous devons utiliser Two stack .i.e Stack s1 et Stack s2.

  1. Initialement, les deux piles sont vides, alors ajoutez des éléments aux deux piles

--------------------- Appelez récursivement les étapes 2 à 4 -----------------------

  1. si Nouvel élément ajouté à la pile s1.Then les éléments de la pile s2

  2. compare les nouveaux éléments avec s2. lequel est plus petit, appuyez sur s2.

  3. pop de la pile s2 (qui contient l'élément min)

Le code ressemble à:

package Stack;
import Java.util.Stack;
public class  getMin 
{  

        Stack<Integer> s1= new Stack<Integer>();
        Stack<Integer> s2 = new Stack<Integer>();

        void Push(int x)
        {
            if(s1.isEmpty() || s2.isEmpty())

            {
                 s1.Push(x);
                 s2.Push(x);
            }
            else
            {

               s1. Push(x);
                int y = (Integer) s2.pop();
                s2.Push(y);
                if(x < y)
                    s2.Push(x);
                        }
        }
        public Integer pop()
        {
            int x;
            x=(Integer) s1.pop();
            s2.pop();
            return x;

        }
    public  int getmin()
        {
            int x1;
            x1= (Integer)s2.pop();
            s2.Push(x1);
            return x1;
        }

    public static void main(String[] args) {
        getMin s = new getMin();
            s.Push(10);
            s.Push(20);
            s.Push(30);
            System.out.println(s.getmin());
            s.Push(1);
            System.out.println(s.getmin());
        }

}
0
RAJNISH YADAV
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Solution 
{
    public class MinStack
    {
        public MinStack()
        {
            MainStack=new Stack<int>();
            Min=new Stack<int>();
        }

        static Stack<int> MainStack;
        static Stack<int> Min;

        public void Push(int item)
        {
            MainStack.Push(item);

            if(Min.Count==0 || item<Min.Peek())
                Min.Push(item);
        }

        public void Pop()
        {
            if(Min.Peek()==MainStack.Peek())
                Min.Pop();
            MainStack.Pop();
        }
        public int Peek()
        {
            return MainStack.Peek();
        }

        public int GetMin()
        {
            if(Min.Count==0)
                throw new System.InvalidOperationException("Stack Empty"); 
            return Min.Peek();
        }
    }
}
0
struct Node {
    let data: Int
    init(_ d:Int){
        data = d
    }
}

struct Stack {
    private var backingStore = [Node]()
    private var minArray = [Int]()

    mutating func Push(n:Node) {
        backingStore.append(n)
        minArray.append(n.data)
        minArray.sort(>)
        minArray
    }

    mutating func pop() -> Node? {
        if(backingStore.isEmpty){
            return nil
        }

        let n = backingStore.removeLast()

        var found = false
        minArray = minArray.filter{
            if (!found && $0 == n.data) {
                found = true
                return false
            }
            return true
        }
        return n
    }

    func min() -> Int? {
        return minArray.last
    }
}
0
Edward Ashak

Supposons que la pile sur laquelle nous allons travailler est la suivante:

6 , minvalue=2
2 , minvalue=2
5 , minvalue=3
3 , minvalue=3
9 , minvalue=7
7 , minvalue=7
8 , minvalue=8

Dans la représentation ci-dessus, la pile n'est construite que par la valeur de gauche. La valeur de droite [minvalue] est écrite uniquement à des fins d'illustration et sera stockée dans une variable.

Le problème actuel est lorsque la valeur qui est la valeur minimale est supprimée à ce moment-là, comment pouvons-nous savoir quel est le prochain élément minimum sans effectuer une itération sur la pile.

Comme par exemple dans notre pile lorsque 6 get est sauté, nous savons que ce n'est pas l'élément minimum car l'élément minimum est 2, nous pouvons donc le supprimer en toute sécurité sans mettre à jour notre valeur min.

Mais lorsque nous passons 2, nous pouvons voir que la valeur minimum est 2 en ce moment et si cela disparaît, nous devons mettre à jour la valeur minimum sur 3.

Point1:

Maintenant, si vous observez attentivement, nous devons générer minvalue = 3 à partir de cet état particulier [2, minvalue = 2]. ou si vous dépilez la pile, nous devons générer minvalue = 7 à partir de cet état particulier [3, minvalue = 3] ou si vous dépassez davantage la pile, nous devons générer minvalue = 8 à partir de cet état particulier [7, minvalue = 7]

Avez-vous remarqué quelque chose de commun dans les 3 cas ci-dessus, la valeur que nous devons générer dépend de deux variables égales. Correct. Pourquoi cela se produit-il parce que lorsque nous envoyons un élément plus petit que la valeur minimale actuelle, nous enfonçons essentiellement cet élément dans la pile et mettons également à jour le même nombre dans valeur min.

Point2:

Nous stockons donc essentiellement les doublons du même nombre une fois dans la pile et une fois dans la variable minvalue. Nous devons nous efforcer d'éviter cette duplication et stocker des données utiles dans la pile ou dans la valeur minimale afin de générer le minimum précédent, comme indiqué dans CASES ci-dessus.

Concentrons-nous sur ce que nous devrions stocker dans la pile lorsque la valeur à stocker dans Push est inférieure à la valeur minimale. Appelons cette variable y, donc maintenant notre pile ressemblera à ceci:

6 , minvalue=2
y1 , minvalue=2
5 , minvalue=3
y2 , minvalue=3
9 , minvalue=7
y3 , minvalue=7
8 , minvalue=8

Je les ai renommés y1, y2, y3 pour éviter toute confusion selon laquelle ils auront tous la même valeur.

Point3:

Maintenant, essayons de trouver une contrainte sur y1, y2 et y3. Vous souvenez-vous quand exactement nous devons mettre à jour la valeur minimale en faisant pop (), uniquement lorsque nous avons ajouté l'élément qui est égal à la valeur min. Si nous affichons quelque chose de plus grand que la valeur minimale, nous n'avons pas à mettre à jour la valeur minimale. Donc, pour déclencher la mise à jour de minvalue, y1, y2 et y3 devraient être plus petits que la valeur minimale correspondante. [Nous avodons l'égalité pour éviter les doublons [Point2]], donc la contrainte est [y <minValue].

Revenons maintenant pour peupler y, nous devons générer une valeur et y mettre au moment du Push, rappelez-vous. Prenons la valeur qui arrive pour Push à x, qui est inférieure à prevMinvalue, et la valeur que nous allons réellement pousser dans la pile à y. Il est donc évident que newMinValue = x et y <newMinvalue.

Maintenant, nous devons calculer y (rappelez-vous que y peut être n'importe quel nombre inférieur à newMinValue (x), nous devons donc trouver un nombre pouvant satisfaire notre contrainte) à l'aide de prevMinvalue et x (newMinvalue).

Let's do the math:
    x < prevMinvalue [Given]
    x - prevMinvalue < 0 
    x - prevMinValue + x < 0 + x [Add x on both side]
    2*x - prevMinValue < x      
this is the y which we were looking for less than x(newMinValue).
y = 2*x - prevMinValue. 'or' y = 2*newMinValue - prevMinValue 'or' y = 2*curMinValue - prevMinValue [taking curMinValue=newMinValue].

Donc, au moment de pousser x si il est inférieur à prevMinvalue, nous poussons y [2 * x-prevMinValue] et mettons à jour newMinValue = x.

Et au moment du pop, si la pile contient quelque chose de moins que minValue, c’est notre déclencheur pour mettre à jour minValue. Nous devons calculer prevMinValue à partir de la CurMinValue et y. y = 2 * curMinValue - prevMinValue [Prouvé] prevMinVAlue = 2 * curMinvalue - y.

2 * curMinValue - y est le nombre que nous devons mettre à jour maintenant pour prevMinValue.

Le code pour la même logique est partagé ci-dessous avec O(1) time et O(1) complexité de l'espace.

// C++ program to implement a stack that supports 
// getMinimum() in O(1) time and O(1) extra space. 
#include <bits/stdc++.h> 
using namespace std; 

// A user defined stack that supports getMin() in 
// addition to Push() and pop() 
struct MyStack 
{ 
    stack<int> s; 
    int minEle; 

    // Prints minimum element of MyStack 
    void getMin() 
    { 
        if (s.empty()) 
            cout << "Stack is empty\n"; 

        // variable minEle stores the minimum element 
        // in the stack. 
        else
            cout <<"Minimum Element in the stack is: "
                 << minEle << "\n"; 
    } 

    // Prints top element of MyStack 
    void peek() 
    { 
        if (s.empty()) 
        { 
            cout << "Stack is empty "; 
            return; 
        } 

        int t = s.top(); // Top element. 

        cout << "Top Most Element is: "; 

        // If t < minEle means minEle stores 
        // value of t. 
        (t < minEle)? cout << minEle: cout << t; 
    } 

    // Remove the top element from MyStack 
    void pop() 
    { 
        if (s.empty()) 
        { 
            cout << "Stack is empty\n"; 
            return; 
        } 

        cout << "Top Most Element Removed: "; 
        int t = s.top(); 
        s.pop(); 

        // Minimum will change as the minimum element 
        // of the stack is being removed. 
        if (t < minEle) 
        { 
            cout << minEle << "\n"; 
            minEle = 2*minEle - t; 
        } 

        else
            cout << t << "\n"; 
    } 

    // Removes top element from MyStack 
    void Push(int x) 
    { 
        // Insert new number into the stack 
        if (s.empty()) 
        { 
            minEle = x; 
            s.Push(x); 
            cout <<  "Number Inserted: " << x << "\n"; 
            return; 
        } 

        // If new number is less than minEle 
        if (x < minEle) 
        { 
            s.Push(2*x - minEle); 
            minEle = x; 
        } 

        else
           s.Push(x); 

        cout <<  "Number Inserted: " << x << "\n"; 
    } 
}; 

// Driver Code 
int main() 
{ 
    MyStack s; 
    s.Push(3); 
    s.Push(5); 
    s.getMin(); 
    s.Push(2); 
    s.Push(1); 
    s.getMin(); 
    s.pop(); 
    s.getMin(); 
    s.pop(); 
    s.peek(); 

    return 0; 
} 
0
Rajat Gautam