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