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 gauche, la valeur [minvalue] de droite est écrite uniquement à des fins d'illustration qui sera stockée dans une variable.
Le problème réel est lorsque la valeur qui est la valeur minimale est supprimée à ce stade, comment pouvons-nous savoir quel est le prochain élément minimum sans itérer sur la pile.
Comme par exemple dans notre pile lorsque 6 get apparaît, 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 pop 2, nous pouvons voir que la valeur minimale est de 2 pour le moment et si cela apparaît, nous devons mettre à jour la valeur minimale à 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 allez depper dans la pile, nous devons générer minvalue = 7 à partir de cet état particulier [3, minvalue = 3] ou si vous allez plus loin dans la pile, nous devons générer minvalue = 8 à partir de cet état particulier [7, minvalue = 7]
Avez-vous remarqué quelque chose en commun dans tous les 3 cas ci-dessus, la valeur que nous devons générer dépend de deux variables qui sont toutes deux égales. Correct. Pourquoi cela se produit-il parce que lorsque nous poussons un élément plus petit que la valeur minimale actuelle, nous poussons essentiellement cet élément dans la pile et mettons également à jour le même nombre dans la valeur minimale.
Point2:
Nous stockons donc essentiellement un double du même nombre une fois dans la pile et une fois dans la variable minvalue. Nous devons nous concentrer pour éviter cette duplication et stocker des données utiles dans la pile ou la valeur min pour générer le minimum précédent, comme indiqué dans CASES ci-dessus.
Concentrons-nous sur ce que nous devons stocker dans la pile lorsque la valeur à stocker dans push est inférieure à la valeur minmum. 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 tous auront la même valeur.
Point3:
Essayons maintenant de trouver des contraintes sur y1, y2 et y3. Vous souvenez-vous quand exactement nous avons besoin de mettre à jour la valeur min en faisant pop (), seulement quand nous avons sauté 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 besoin de mettre à jour la valeur minimale. Donc, pour déclencher la mise à jour de la valeur min, y1, y2 et y3 doivent être plus petits que la valeur min correspondante. [Nous avodons l'égalité pour éviter la duplication [Point2]] donc la contrainte est [y <minValue].
Revenons maintenant à peupler y, nous devons générer une valeur et mettre y au moment du push, rappelez-vous. Prenons la valeur qui vient pour push pour être x qui est inférieure à la prevMinvalue, et la valeur que nous allons réellement pousser dans la pile pour être y. Une chose est donc évidente: 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 qui puisse remplir 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 s'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 la minValue, c'est notre déclencheur pour mettre à jour le minVAlue. Nous devons calculer prevMinValue à partir de curMinValue et y. y = 2 * curMinValue - prevMinValue [Prouvé] prevMinVAlue = 2 * curMinvalue - y.
2 * curMinValue - y est le nombre que nous devons mettre à jour maintenant vers prevMinValue.
Le code pour la même logique est partagé ci-dessous avec la complexité du temps O (1) et de l'espace O (1).
// 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;
}