Entwerfen Sie einen Stapel so, dass getMinimum () O (1) sein sollte.

118

Dies ist eine Interviewfrage. Sie müssen einen Stapel entwerfen, der einen ganzzahligen Wert enthält, sodass die Funktion getMinimum () das minimale Element im Stapel zurückgeben soll.

Zum Beispiel: Betrachten Sie das folgende Beispiel

Fall 1

5 -> TOP
1
4
6
2

Wenn getMinimum () aufgerufen wird, sollte es 1 zurückgeben, was das minimale Element ist 
im Stapel. 

Fall 2

stack.pop ()
stack.pop ()

Hinweis: Sowohl 5 als auch 1 werden aus dem Stapel entfernt. Also danach der Stapel
sieht aus wie,

4 -> TOP
6
2

Wenn getMinimum () aufgerufen wird, sollte is 2 zurückgeben, was das Minimum in der ist 
Stapel.

Constriants:

  1. getMinimum sollte den Minimalwert in O (1) zurückgeben.
  2. Bei der Gestaltung muss auch die Platzbeschränkung berücksichtigt werden. Wenn Sie zusätzlichen Platz verwenden, sollte der Platz konstant sein.
Ganesh M.
quelle

Antworten:

180

BEARBEITEN: Dadurch wird die Einschränkung "konstanter Speicherplatz" nicht erfüllt - der erforderliche Speicherplatz wird grundsätzlich verdoppelt. Ich bezweifle sehr, dass es eine Lösung gibt, die dies jedoch nicht tut, ohne die Laufzeitkomplexität irgendwo zu zerstören (z. B. Push / Pop O (n)). Beachten Sie, dass dies die Komplexität des erforderlichen Speicherplatzes nicht ändert. Wenn Sie beispielsweise einen Stapel mit O (n) Speicherplatzbedarf haben, ist dies immer noch O (n), nur mit einem anderen konstanten Faktor.

Nicht konstante Raumlösung

Halten Sie einen "doppelten" Stapel von "Minimum aller Werte niedriger im Stapel". Wenn Sie den Hauptstapel platzen lassen, platzen Sie auch den Min-Stapel. Wenn Sie den Hauptstapel drücken, drücken Sie entweder das neue Element oder die aktuelle min, je nachdem, welcher Wert niedriger ist. getMinimum()wird dann als gerecht implementiert minStack.peek().

Anhand Ihres Beispiels hätten wir also:

Real stack        Min stack

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

Nach zweimaligem Poppen erhalten Sie:

Real stack        Min stack

4                 2
6                 2
2                 2

Bitte lassen Sie mich wissen, wenn dies nicht genug Informationen sind. Es ist einfach, wenn du es grokst, aber es könnte zuerst ein bisschen Kopfkratzen erfordern :)

(Der Nachteil ist natürlich, dass sich der Platzbedarf verdoppelt. Die Ausführungszeit leidet jedoch nicht wesentlich - dh sie ist immer noch gleich komplex.)

EDIT: Es gibt eine Variante, die etwas fummeliger ist, aber im Allgemeinen einen besseren Platz bietet. Wir haben immer noch den Min-Stack, aber wir öffnen ihn nur, wenn der Wert, den wir vom Hauptstapel entfernen, dem auf dem Min-Stack entspricht. Wir pushen nur auf den Min-Stapel, wenn der Wert, der auf den Hauptstapel verschoben wird, kleiner oder gleich dem aktuellen Min-Wert ist. Dies ermöglicht doppelte Mindestwerte. getMinimum()ist immer noch nur eine Peek-Operation. Wenn wir zum Beispiel die Originalversion nehmen und erneut 1 drücken, erhalten wir:

Real stack        Min stack

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

Das Knallen von oben taucht von beiden Stapeln auf, weil 1 == 1, so dass:

Real stack        Min stack

5  --> TOP        1
1                 2
4                 
6                 
2                 

Das erneute Poppen wird nur vom Hauptstapel entfernt, da 5> 1:

Real stack        Min stack

1                 1
4                 2
6                 
2                 

Beim erneuten Poppen werden beide Stapel angezeigt, da 1 == 1:

Real stack        Min stack

4                 2
6                 
2                 

Dies führt zu der gleichen Speicherplatzkomplexität im ungünstigsten Fall (doppelt so viel wie der ursprüngliche Stapel), aber zu einer viel besseren Speicherplatznutzung, wenn wir selten ein "neues Minimum oder gleich" erhalten.

EDIT: Hier ist eine Implementierung von Petes bösem Schema. Ich habe es nicht gründlich getestet, aber ich denke es ist okay :)

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;
    }
}
Jon Skeet
quelle
3
Klug! @ Ganesh: Warum sollte die Laufzeit ein Problem sein? Es dauert nur doppelt so lange wie ein einzelner Stapel, dh es ist immer noch O (1) Zeit für Push () und Pop () sowie für getMinimum () - das ist eine hervorragende Leistung!
j_random_hacker
4
Wenn Sie eine einzelne Variable haben, was passiert, wenn Sie in Ihrem Beispiel die "1" eingeben? Es muss sich herausstellen, dass das vorherige Minimum "2" war - was es nicht kann, ohne alles zu scannen.
Jon Skeet
1
@ Ganesh: Müssen Sie dann nicht das neue Minimum mithilfe einer O (n) -Suche finden, wenn Sie pop ()?
j_random_hacker
2
Wenn Sie nur Ihre anderen Kommentare lesen und "im Stapelentwurf selbst" sagen, meinen Sie "in jedem Element"? In diesem Fall können Sie den Speicherbedarf je nach Größe des Elementtyps möglicherweise nahezu verdoppeln. Es ist konzeptionell dasselbe wie zwei Stapel.
Jon Skeet
1
@ Ganesh: Wenn wir leider keinen zusätzlichen Stack haben, können wir die oben angegebene platzsparende Optimierung nicht durchführen. Das Zusammenhalten von "Minimum und Element" ist wahrscheinlich effizienter als zwei Stapel derselben Größe (weniger Overhead - Arrays, Listenknoten usw.), obwohl dies von der Sprache abhängt.
Jon Skeet
41

Fügen Sie ein Feld hinzu, das den Mindestwert enthält, und aktualisieren Sie es während Pop () und Push (). Auf diese Weise wird getMinimum () O (1) sein, aber Pop () und Push () müssen etwas mehr Arbeit leisten.

Wenn der Mindestwert angezeigt wird, ist Pop () O (n), andernfalls sind beide immer noch O (1). Beim Ändern der Größe wird Push () gemäß der Stack-Implementierung zu O (n).

Hier ist eine schnelle Implementierung

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; } }
}
Brian Rasmussen
quelle
Entschuldigung, ich habe nicht verstanden, warum Pop () und Push () leiden werden.
Ganesh M
11
In pop () muss das "neue" minimale Element gefunden werden, das O (n) annimmt. Push () wird nicht leiden, da dieser Vorgang immer noch O (1) ist.
Georg Schölly
4
@ Sigjuice: richtig. Ich denke, ich werde das Wort "leiden" in etwas weniger Dramatisches ändern :)
Brian Rasmussen
2
@Ganesh M "das Elementadditionsfeld" Wenn Sie ein zusätzliches Feld in Ihren N Elementen haben, ist es kein konstanter Raum, sondern O (N) extra.
Pete Kirkham
1
Wenn der Mindestwert während einer Operation aus dem Stapel herausspringt, wie wird dann der nächste Mindestwert gefunden? Diese Methode unterstützt dieses Szenario nicht ...
Sharat Chandra
16
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();
    }

}

Es speichert das aktuelle Minimum explizit und wenn sich das Minimum ändert, drückt es anstelle des Werts einen Wert mit der gleichen Differenz auf die andere Seite des neuen Minimums (wenn min = 7 und Sie 5 drücken, drückt es stattdessen 3 (5-)) | 7-5 | = 3) und setzt min auf 5; wenn Sie dann 3 platzen lassen, wenn min 5 ist, wird angezeigt, dass der Pop-Wert kleiner als min ist. Kehren Sie daher die Prozedur um, um 7 für das neue min zu erhalten, und geben Sie das vorherige zurück Mindest). Da jeder Wert, der keine Änderung verursacht, das aktuelle Minimum größer als das aktuelle Minimum ist, können Sie zwischen Werten, die das Minimum ändern, und Werten, die dies nicht tun, unterscheiden.

In Sprachen, in denen Ganzzahlen mit fester Größe verwendet werden, leihen Sie sich etwas Speicherplatz aus der Darstellung der Werte aus, sodass diese möglicherweise unterlaufen und die Bestätigung fehlschlägt. Ansonsten ist es ein konstanter zusätzlicher Speicherplatz und alle Operationen sind immer noch O (1).

Stapel, die stattdessen auf verknüpften Listen basieren, haben andere Stellen, von denen Sie ein bisschen ausleihen können, z. B. in C das niedrigstwertige Bit des nächsten Zeigers oder in Java den Typ der Objekte in der verknüpften Liste. Für Java bedeutet dies, dass im Vergleich zu einem zusammenhängenden Stapel mehr Speicherplatz verwendet wird, da Sie den Objekt-Overhead pro Link haben:

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;
    }

In C ist der Overhead nicht vorhanden, und Sie können das lsb des nächsten Zeigers ausleihen:

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.;

Keines davon ist jedoch wirklich O (1). In der Praxis benötigen sie keinen Platz mehr, da sie Lücken in der Darstellung von Zahlen, Objekten oder Zeigern in diesen Sprachen ausnutzen. Eine theoretische Maschine, die eine kompaktere Darstellung verwendet, würde jedoch erfordern, dass dieser Darstellung jeweils ein zusätzliches Bit hinzugefügt wird.

Pete Kirkham
quelle
+1 sehr elegant in der Tat ... trivial portierte C ++ - Version, die hier auf ideone läuft . Prost.
Tony Delroy
In Java führt dies zu einem falschen Ergebnis, pop()wenn der letzte Integer.MIN_VALUEPush- Wert war (z. B. Push 1, Push Integer.MIN_VALUE, Pop). Dies ist auf den oben erwähnten Unterlauf zurückzuführen. Andernfalls funktioniert für alle ganzzahligen Werte.
Theo
13

Ich habe eine Lösung gefunden, die alle genannten Einschränkungen (Operationen mit konstanter Zeit) und konstantem zusätzlichen Platz erfüllt .

Die Idee ist, die Differenz zwischen dem Min-Wert und der Eingangsnummer zu speichern und den Min-Wert zu aktualisieren, wenn er nicht mehr das Minimum ist.

Der Code lautet wie folgt:

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;
    }
}

Das Guthaben geht an: https://leetcode.com/discuss/15679/share-my-java-solution-with-only-one-stack

WoLfPwNeR
quelle
Dieser funktioniert. Ich habe es auch mit negativen Zahlen im Stapel versucht. Und einfach genug, um sich auch zu erinnern. Vielen Dank.
r9891
7

Nun, was sind die Laufzeitbeschränkungen von pushund pop? Wenn sie nicht konstant sein müssen, berechnen Sie einfach den Mindestwert in diesen beiden Operationen (machen Sie sie zu O ( n )). Ansonsten sehe ich nicht, wie dies mit konstantem zusätzlichen Platz gemacht werden kann.

Konrad Rudolph
quelle
4
+1, hehe ... Der alte Trick "Regeln biegen" ... In ähnlicher Weise kenne ich einen Sortieralgorithmus, der ein Array beliebiger Größe in O (1) -Zeit sortiert, aber den ersten Zugriff auf ein Element des Ergebnis verursacht O (nlog n) Overhead ... :)
j_random_hacker
3
In Haskell ist alles konstante Zeit! (außer wenn Sie das Ergebnis drucken möchten)
Henk
1
+1 für die Feststellung der schlechten Problemspezifikation. "Ich sehe nicht, wie das gemacht werden kann" - ich auch nicht, aber Pete Kirkhams Lösung macht es sehr elegant ...
Tony Delroy
1

Hier ist mein Code, der mit O (1) läuft. Der vorherige Code, den ich gepostet habe, hatte ein Problem, als das minimale Element platzte. Ich habe meinen Code geändert. Dieser verwendet einen anderen Stapel, der das im Stapel vorhandene Mindestelement über dem aktuell geschobenen Element beibehält.

 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);
    }
}
Akshay
quelle
3
Bitte erwähnen Sie die Programmiersprache, die hier zum Schreiben von Code verwendet wird. Es hilft potenziellen Besuchern, anhand der Syntax zu erkennen, was los ist. Ich nehme an, es ist C #, aber was ist, wenn jemand es nicht tut?
RealPK
1

Ich habe eine andere Art von Stapel verwendet. Hier ist die Implementierung.

//
//  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;
}

Ausgabe:

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

Versuch es. Ich denke, es beantwortet die Frage. Das zweite Element jedes Paares gibt den Mindestwert an, der beim Einfügen dieses Elements angezeigt wurde.

Chaitanya Bilgikar
quelle
1

Ich poste hier den vollständigen Code, um Min und Max in einem bestimmten Stapel zu finden.

Die zeitliche Komplexität beträgt 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());
    }
}

Lassen Sie mich wissen, wenn Sie vor einem Problem stehen

Danke, Vikash

Java Baby
quelle
1

Sie können Ihre ursprüngliche Stapelklasse erweitern und einfach das Min-Tracking hinzufügen. Lassen Sie die ursprüngliche übergeordnete Klasse alles andere wie gewohnt behandeln.

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();
    }   
}
Arcturus
quelle
Diese Lösung benötigt auch zusätzlichen Speicherplatz in Bezug auf Stack <Integer> min.
Arpit
1

Hier ist meine Lösung in Java mit Likes-Liste.

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;
  }

}}

Irshad ck
quelle
1

Nehmen wir an, der Stapel, an dem wir arbeiten werden, ist folgender:

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

In der obigen Darstellung wird der Stapel nur durch den linken Wert erstellt. Der [Minimalwert] des rechten Werts wird nur zu Illustrationszwecken geschrieben, die in einer Variablen gespeichert werden.

Das eigentliche Problem ist, wenn der Wert, der der Minimalwert ist, an diesem Punkt entfernt wird. Wie können wir wissen, was das nächste minimale Element ist, ohne über den Stapel zu iterieren?

Wie zum Beispiel in unserem Stapel, wenn 6 get's platzen, wissen wir, dass dies nicht das minimale Element ist, da das minimale Element 2 ist, sodass wir dies sicher entfernen können, ohne unseren minimalen Wert zu aktualisieren.

Aber wenn wir 2 platzen lassen, können wir sehen, dass der Mindestwert gerade 2 ist. Wenn dieser Wert herausspringt, müssen wir den Mindestwert auf 3 aktualisieren.

Punkt 1:

Wenn Sie nun genau beobachten, müssen wir aus diesem bestimmten Zustand einen Minimalwert = 3 erzeugen [2, Minuswert = 2]. oder wenn Sie den Stapel depperinieren, müssen wir aus diesem bestimmten Zustand minvalue = 7 generieren [3, minvalue = 3], oder wenn Sie im Stapel depper werden, müssen wir aus diesem bestimmten Zustand minvalue = 8 generieren [7, minvalue = 7]

Haben Sie in allen drei oben genannten Fällen etwas gemeinsam bemerkt? Der Wert, den wir generieren müssen, hängt von zwei Variablen ab, die beide gleich sind. Richtig. Warum passiert das, weil wir, wenn wir ein Element verschieben, das kleiner als der aktuelle Minimalwert ist, dieses Element im Grunde genommen in den Stapel verschieben und dieselbe Zahl auch im Minimalwert aktualisieren.

Punkt 2:

Wir speichern also im Grunde ein Duplikat derselben Nummer einmal im Stapel und einmal in der Variablen minvalue. Wir müssen uns darauf konzentrieren, diese Duplizierung zu vermeiden und nützliche Daten im Stapel oder im Minimalwert zu speichern, um das vorherige Minimum zu generieren, wie in den obigen FÄLLEN gezeigt.

Konzentrieren wir uns darauf, was im Stapel gespeichert werden soll, wenn der in Push zu speichernde Wert kleiner als der Mindestwert ist. Nennen wir diese Variable y, also sieht unser Stapel jetzt ungefähr so ​​aus:

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

Ich habe sie in y1, y2, y3 umbenannt, um Verwirrung zu vermeiden, dass alle den gleichen Wert haben.

Punkt 3:

Versuchen wir nun, einige Einschränkungen über y1, y2 und y3 zu finden. Erinnern Sie sich, wann genau wir den Minimalwert aktualisieren müssen, während Sie pop () ausführen, nur wenn wir das Element gepoppt haben, das dem Minimalwert entspricht? Wenn wir etwas Größeres als den Mindestwert anzeigen, müssen wir den Mindestwert nicht aktualisieren. Um die Aktualisierung des Min-Werts auszulösen, sollten y1, y2 und y3 kleiner sein als der entsprechende Min-Wert.

Kommen wir nun zurück, um y zu füllen. Wir müssen einen Wert generieren und y zum Zeitpunkt des Pushs setzen. Denken Sie daran. Nehmen wir den Wert, der für Push kommt, als x, was kleiner als der prevMinvalue ist, und den Wert, den wir tatsächlich im Stapel pushen, als y. Eines ist also offensichtlich: newMinValue = x und y <newMinvalue.

Jetzt müssen wir y mit Hilfe von prevMinvalue und x (newMinvalue) berechnen (denken Sie daran, dass y eine beliebige Zahl sein kann, die kleiner als newMinValue (x) ist, also müssen wir eine Zahl finden, die unsere Einschränkung erfüllen kann).

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].

Zum Zeitpunkt des Drückens von x, wenn es kleiner als prevMinvalue ist, drücken wir y [2 * x-prevMinValue] und aktualisieren newMinValue = x.

Und wenn zum Zeitpunkt des Popens der Stapel etwas weniger als den minValue enthält, ist dies unser Auslöser für die Aktualisierung des minVAlue. Wir müssen prevMinValue aus dem curMinValue und y berechnen. y = 2 * curMinValue - prevMinValue [Bewiesen] prevMinVAlue = 2 * curMinvalue - y.

2 * curMinValue - y ist die Nummer, die wir jetzt auf den prevMinValue aktualisieren müssen.

Der Code für dieselbe Logik wird unten mit der Komplexität von O (1) Zeit und O (1) Raum geteilt.

// 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; 
} 
Rajat Gautam
quelle
0

Hier ist meine Version der Implementierung.

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

 void Push (int value)
 {
    // Erstelle deine Struktur und fülle den Wert
    MyStack S = neuer MyStack ();
    S-> Element = Wert;

    if (Stack.Empty ())
    {    
        // Da der Stapel leer ist, zeigen Sie mit CurrentMiniAddress auf sich selbst
        S-> CurrentMiniAddress = S;

    }}
    sonst
    {
         // Stapel ist nicht leer

         // Das oberste Element abrufen. Kein Pop ()
         MyStack * TopElement = Stack.Top ();

         // Denken Sie daran, dass das TOP-Element immer auf das zeigt
         // minimales Element im gesamten Stapel
         if (S-> Element CurrentMiniAddress-> Element)
         {
            // Wenn der aktuelle Wert das Minimum im gesamten Stapel ist
            // dann zeigt S auf sich selbst
            S-> CurrentMiniAddress = S;
         }}
             sonst
             {
                 // Dies ist also nicht das Minimum im gesamten Stapel
                 // Keine Sorge, TOP hält das minimale Element
                 S-> CurrentMiniAddress = TopElement-> CurrentMiniAddress;
             }}

    }}
        Stack.Add (S);
 }}

 void Pop ()
 {
     if (! Stack.Empty ())
     {
        Stack.Pop ();
     }}  
 }}

 int GetMinimum (Stack & Stack)
 {
       if (! stack.Empty ())
       {
            MyStack * Top = stack.top ();
            // Top zeigt immer auf das Minimumx
            return Top-> CurrentMiniAddress-> element;
        }}
 }}
Ganesh M.
quelle
Ich stimme zu, dies erfordert ein zusätzliches Element in Ihrer Struktur. Dadurch entfällt jedoch das Finden des Minimums, wenn ein Element eingeblendet wird.
Ganesh M
1
Haben Sie den Job bekommen, nachdem Sie die Einschränkungen der Frage nicht erfüllt haben?
Pete Kirkham
0
#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);
}
}
Tauqir Azam
quelle
0

Ich habe diese Lösung hier gefunden

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;
};
isxaker
quelle
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
    }
}
Edward Ashak
quelle
0
 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);

}
}
Mayank
quelle
0
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();
    }
}
KM Fazle Azim Babu
quelle
0

Hier ist mein Code, der mit O (1) läuft. Hier habe ich ein Vektorpaar verwendet, das den Wert enthält, der gedrückt wurde, und auch den Mindestwert bis zu diesem Wert enthält.


Hier ist meine Version der C ++ - Implementierung.

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 
    }
};
ein Kind
quelle
0
    **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 */
Akhil Gupta
quelle
Was trägt dies beispielsweise zu Jon Skeets Antwort bei ? Wie viel Platz benötigt dies für n gegen unendlich (siehe Frage oder die verknüpfte Antwort)? Mit einer Programmiersprache, die behauptet, OO zu unterstützen, erscheint es angemessener, einen (nicht so abstrakten) Datentyp / (generisch) Class- MinStack? In der Java-Dokumentation von Oracle wird empfohlen, diese zu verwenden Deque.
Graubart
(Vielen Dank für Ihre Hinweise. (Code-Kommentare sollten erklären, wofür, wie und warum - zu erwähnen, dass eine Bedingung eine Bedingung ist, ist nicht hilfreich. Die ersten ein oder zwei Zeilen sollten besser nicht eingerückt werden, es wird erreicht, aktuell, wobei , geschrumpft und erweitert …))
Graubart
0

Eine praktische Implementierung zum Finden eines Minimums in einem Stapel von benutzerdefinierten Objekten mit dem Namen: Schule

Der Stapel speichert die Schulen im Stapel basierend auf dem Rang, der einer Schule in einer bestimmten Region zugewiesen wurde. FindMin () gibt der Schule an, wo wir die maximale Anzahl von Zulassungsanträgen erhalten, die wiederum von der Schule definiert werden Komparator, der den Rang verwendet, der den Schulen in der vorherigen Saison zugeordnet wurde.

The Code for same is below:


   package com.practical;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class CognitaStack {

    public School findMin(Stack<School> stack, Stack<School> minStack) {

        if (!stack.empty() && !minStack.isEmpty())
            return (School) minStack.peek();
        return null;
    }

    public School removeSchool(Stack<School> stack, Stack<School> minStack) {

        if (stack.isEmpty())
            return null;
        School temp = stack.peek();
        if (temp != null) {
            // if(temp.compare(stack.peek(), minStack.peek())<0){
            stack.pop();
            minStack.pop();
            // }

            // stack.pop();
        }
        return stack.peek();
    }

    public static void main(String args[]) {

        Stack<School> stack = new Stack<School>();
        Stack<School> minStack = new Stack<School>();

        List<School> lst = new LinkedList<School>();

        School s1 = new School("Polam School", "London", 3);
        School s2 = new School("AKELEY WOOD SENIOR SCHOOL", "BUCKINGHAM", 4);
        School s3 = new School("QUINTON HOUSE SCHOOL", "NORTHAMPTON", 2);
        School s4 = new School("OAKLEIGH HOUSE SCHOOL", " SWANSEA", 5);
        School s5 = new School("OAKLEIGH-OAK HIGH SCHOOL", "Devon", 1);
        School s6 = new School("BritishInter2", "Devon", 7);

        lst.add(s1);
        lst.add(s2);
        lst.add(s3);
        lst.add(s4);
        lst.add(s5);
        lst.add(s6);

        Iterator<School> itr = lst.iterator();
        while (itr.hasNext()) {
            School temp = itr.next();
            if ((minStack.isEmpty()) || (temp.compare(temp, minStack.peek()) < 0)) { // minStack.peek().equals(temp)
                stack.push(temp);
                minStack.push(temp);
            } else {
                minStack.push(minStack.peek());
                stack.push(temp);
            }

        }

        CognitaStack cogStack = new CognitaStack();
        System.out.println(" Minimum in Stack is " + cogStack.findMin(stack, minStack).name);
        cogStack.removeSchool(stack, minStack);
        cogStack.removeSchool(stack, minStack);

        System.out.println(" Minimum in Stack is "
                + ((cogStack.findMin(stack, minStack) != null) ? cogStack.findMin(stack, minStack).name : "Empty"));
    }

}

Auch das Schulobjekt lautet wie folgt:

package com.practical;

import java.util.Comparator;

public class School implements Comparator<School> {

    String name;
    String location;
    int rank;

    public School(String name, String location, int rank) {
        super();
        this.name = name;
        this.location = location;
        this.rank = rank;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((location == null) ? 0 : location.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + rank;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        School other = (School) obj;
        if (location == null) {
            if (other.location != null)
                return false;
        } else if (!location.equals(other.location))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (rank != other.rank)
            return false;
        return true;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public int compare(School o1, School o2) {
        // TODO Auto-generated method stub
        return o1.rank - o2.rank;
    }

}

class SchoolComparator implements Comparator<School> {

    public int compare(School o1, School o2) {
        return o1.rank - o2.rank;
    }

}

Dieses Beispiel behandelt Folgendes: 1. Implementierung des Stapels für benutzerdefinierte Objekte, hier Schule 2. Implementierung für die Methoden hashcode () und equals () unter Verwendung aller zu vergleichenden Objektfelder 3. Eine praktische Implementierung für das Szenario, in dem wir rqeuire, um den Stapel zu erhalten, enthält eine Operation in der Reihenfolge O (1)

Akhil Gupta
quelle
Zu dieser Frage gibt es kein Sprach-Tag (ganz im Gegenteil language-agnostic:): Bitte geben Sie an, was Sie für den Code verwenden (und entfernen Sie die Leerzeichen zuvor The Code for same is below:). Wie unterstützt dies stack.pop()? (und push()?)
Graubart
0

Hier ist die PHP-Implementierung dessen, was in Jon Skeets Antwort als etwas bessere Implementierung der Raumkomplexität erklärt wurde, um das Maximum an Stack in O (1) zu erhalten.

<?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
sepehr
quelle
0

Hier ist die C ++ - Implementierung von Jon Skeets Answer . Es ist vielleicht nicht die optimalste Art, es zu implementieren, aber es macht genau das, was es soll.

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;
    }
};

Und hier ist der Fahrer für die Klasse

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;
}

Ausgabe:

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

Wir können dies in O (n) Zeit und O (1) Raumkomplexität tun, wie folgt:

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
AnukuL
quelle
0

Ich denke, Sie können einfach eine LinkedList in Ihrer Stack-Implementierung verwenden.

Wenn Sie zum ersten Mal einen Wert drücken, geben Sie diesen Wert als Kopf für die verknüpfte Liste ein.

Führen Sie dann jedes Mal, wenn Sie einen Wert drücken, wenn der neue Wert <head.data ist, eine Prepand-Operation aus (was bedeutet, dass der Kopf zum neuen Wert wird).

Wenn nicht, führen Sie eine Append-Operation durch.

Wenn Sie ein pop () machen, überprüfen Sie, ob min == linkedlist.head.data, wenn ja, dann head = head.next;

Hier ist mein 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();

}

 }
Zok
quelle
Haben Sie eine Folge von Zahlen. Wenn die Zahl in einer Schleife gerade ist, fügen Sie zwei Elemente hinzu. Drücken Sie die Nummer und drucken Sie das Minimum.
Graubart
? Ich verstehe Ihren Kommentar nicht
Zok
Wir können die pop () -Methode anpassen, um zu überprüfen, ob der oberste Wert == 0 ist. Wenn ja, löschen wir die verknüpfte Liste, indem wir min.head = null, min.head.next = null machen
Zok
0
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);
    }
}
Nitin Taur
quelle
0
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();
        }
    }
}
Jagadeesh Bandlamudi
quelle
0

Ich habe hier eine brillante Lösung gesehen: https://www.geeksforgeeks.org/design-a-stack-that-supports-getmin-in-o1-time-and-o1-extra-space/

Unten ist der Python-Code, den ich mit dem folgenden Algorithmus geschrieben habe:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class MinStack:
    def __init__(self):
        self.head = None
        self.min = float('inf')

    # @param x, an integer
    def push(self, x):
        if self.head == None:
            self.head = Node(x)
            self.min = x
        else:
            if x >= self.min:
                n = Node(x)
                n.next = self.head
                self.head = n
            else:
                v = 2 * x - self.min
                n = Node(v)
                n.next = self.head
                self.head = n
                self.min = x

    # @return nothing
    def pop(self):
        if self.head:
            if self.head.value < self.min:
                self.min = self.min * 2 - self.head.value
            self.head = self.head.next

    # @return an integer
    def top(self):
        if self.head:
            if self.head.value < self.min:
                self.min = self.min * 2 - self.head.value
                return self.min
            else:
                return self.head.value
        else:
            return -1

    # @return an integer
    def getMin(self):
        if self.head:
            return self.min
        else:
            return -1
ibic
quelle
0

Um Min-Elemente von Stack zu erhalten. Wir müssen Two Stack .ie Stack s1 und Stack s2 verwenden.

  1. Anfangs sind beide Stapel leer. Fügen Sie daher beiden Stapeln Elemente hinzu

--------------------- Rufen Sie rekursiv die Schritte 2 bis 4 auf -----------------------

  1. Wenn neues Element zum Stapel s1 hinzugefügt wurde. Dann Pop-Elemente vom Stapel s2

  2. vergleiche neue elments mit s2. welches kleiner ist, drücke auf s2.

  3. Pop vom Stapel s2 (der min Element enthält)

Code sieht aus wie:

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());
        }

}
RAJNISH YADAV
quelle
-1

Ich denke nur die Push-Operation leidet, ist genug. Meine Implementierung enthält einen Stapel von Knoten. Jeder Knoten enthält das Datenelement und auch das Minimum in diesem Moment. Dieses Minimum wird jedes Mal aktualisiert, wenn ein Push-Vorgang ausgeführt wird.

Hier sind einige Punkte zum Verständnis:

  • Ich habe den Stack mit Linked List implementiert.

  • Ein Zeiger oben zeigt immer auf das zuletzt geschobene Element. Wenn sich kein Element in diesem Stapel befindet, ist die Oberseite NULL.

  • Wenn ein Element verschoben wird, wird ein neuer Knoten zugewiesen, der einen nächsten Zeiger hat, der auf den vorherigen Stapel zeigt, und oben wird aktualisiert, um auf diesen neuen Knoten zu zeigen.

Der einzige Unterschied zur normalen Stack-Implementierung besteht darin, dass während des Pushs ein Mitglied min für den neuen Knoten aktualisiert wird.

Bitte schauen Sie sich den Code an, der zu Demonstrationszwecken in C ++ implementiert ist.

/*
 *  Implementation of Stack that can give minimum in O(1) time all the time
 *  This solution uses same data structure for minimum variable, it could be implemented using pointers but that will be more space consuming
 */

#include <iostream>
using namespace std;

typedef struct stackLLNodeType stackLLNode;

struct stackLLNodeType {
    int item;
    int min;
    stackLLNode *next;
};

class DynamicStack {
private:
    int stackSize;
    stackLLNode *top;

public:
    DynamicStack();
    ~DynamicStack();
    void push(int x);
    int pop();
    int getMin();
    int size() { return stackSize; }
};

void pushOperation(DynamicStack& p_stackObj, int item);
void popOperation(DynamicStack& p_stackObj);

int main () {
    DynamicStack stackObj;

    pushOperation(stackObj, 3);
    pushOperation(stackObj, 1);
    pushOperation(stackObj, 2);
    popOperation(stackObj);
    popOperation(stackObj);
    popOperation(stackObj);
    popOperation(stackObj);
    pushOperation(stackObj, 4);
    pushOperation(stackObj, 7);
    pushOperation(stackObj, 6);
    popOperation(stackObj);
    popOperation(stackObj);
    popOperation(stackObj);
    popOperation(stackObj);

    return 0;
}

DynamicStack::DynamicStack() {
    // initialization
    stackSize = 0;
    top = NULL;
}

DynamicStack::~DynamicStack() {
    stackLLNode* tmp;
    // chain memory deallocation to avoid memory leak
    while (top) {
        tmp = top;
        top = top->next;
        delete tmp;
    }
}

void DynamicStack::push(int x) {
    // allocate memory for new node assign to top
    if (top==NULL) {
        top = new stackLLNode;
        top->item = x;
        top->next = NULL;
        top->min = top->item;
    }
    else {
        // allocation of memory
        stackLLNode *tmp = new stackLLNode;
        // assign the new item
        tmp->item = x;
        tmp->next = top;

        // store the minimum so that it does not get lost after pop operation of later minimum
        if (x < top->min)
            tmp->min = x;
        else
            tmp->min = top->min;

        // update top to new node
        top = tmp;
    }
    stackSize++;
}

int DynamicStack::pop() {
    // check if stack is empty
    if (top == NULL)
        return -1;

    stackLLNode* tmp = top;
    int curItem = top->item;
    top = top->next;
    delete tmp;
    stackSize--;
    return curItem;
}

int DynamicStack::getMin() {
    if (top == NULL)
        return -1;
    return top->min;
}
void pushOperation(DynamicStack& p_stackObj, int item) {
    cout<<"Just pushed: "<<item<<endl;
    p_stackObj.push(item);
    cout<<"Current stack min: "<<p_stackObj.getMin()<<endl;
    cout<<"Current stack size: "<<p_stackObj.size()<<endl<<endl;
}

void popOperation(DynamicStack& p_stackObj) {
    int popItem = -1;
    if ((popItem = p_stackObj.pop()) == -1 )
        cout<<"Cannot pop. Stack is empty."<<endl;
    else {
        cout<<"Just popped: "<<popItem<<endl;
        if (p_stackObj.getMin() == -1)
            cout<<"No minimum. Stack is empty."<<endl;
        else
            cout<<"Current stack min: "<<p_stackObj.getMin()<<endl;
        cout<<"Current stack size: "<<p_stackObj.size()<<endl<<endl;
    }
}

Und die Ausgabe des Programms sieht folgendermaßen aus:

Just pushed: 3
Current stack min: 3
Current stack size: 1

Just pushed: 1
Current stack min: 1
Current stack size: 2

Just pushed: 2
Current stack min: 1
Current stack size: 3

Just popped: 2
Current stack min: 1
Current stack size: 2

Just popped: 1
Current stack min: 3
Current stack size: 1

Just popped: 3
No minimum. Stack is empty.
Current stack size: 0

Cannot pop. Stack is empty.
Just pushed: 4
Current stack min: 4
Current stack size: 1

Just pushed: 7
Current stack min: 4
Current stack size: 2

Just pushed: 6
Current stack min: 4
Current stack size: 3

Just popped: 6
Current stack min: 4
Current stack size: 2

Just popped: 7
Current stack min: 4
Current stack size: 1

Just popped: 4
No minimum. Stack is empty.
Current stack size: 0

Cannot pop. Stack is empty.
Atiq Rahman
quelle
-1
public interface IMinStack<T extends Comparable<T>> {
  public void push(T val);
  public T pop();
  public T minValue();
  public int size();
}

import java.util.Stack;

public class MinStack<T extends Comparable<T>> implements IMinStack<T> {
  private Stack<T> stack = new Stack<T>();
  private Stack<T> minStack = new Stack<T>();

  @Override
  public void push(T val) {
    stack.push(val);
    if (minStack.isEmpty() || val.compareTo(minStack.peek()) < 0)
        minStack.push(val);
  }

  @Override
  public T pop() {
    T val = stack.pop();
    if ((false == minStack.isEmpty())
            && val.compareTo(minStack.peek()) == 0)
        minStack.pop();
    return val;
  }

  @Override
  public T minValue() {
    return minStack.peek();
  }

  @Override
  public int size() {
    return stack.size();
  }
}
user3798488
quelle