Mari kita asumsikan tumpukan yang akan kita kerjakan adalah ini:
6 , minvalue=2
2 , minvalue=2
5 , minvalue=3
3 , minvalue=3
9 , minvalue=7
7 , minvalue=7
8 , minvalue=8
Pada representasi di atas stack hanya dibangun oleh nilai kiri [nilai min] nilai kanan ditulis hanya untuk tujuan ilustrasi yang akan disimpan dalam satu variabel.
Masalah sebenarnya adalah ketika nilai yang merupakan nilai minimum dihapus pada titik itu bagaimana kita bisa mengetahui apa elemen minimum berikutnya tanpa iterasi di atas tumpukan.
Seperti misalnya di tumpukan kami ketika 6 get muncul, kami tahu bahwa, ini bukan elemen minimum karena elemen minimumnya adalah 2, jadi kami dapat menghapus ini dengan aman tanpa memperbarui nilai min kami.
Tetapi ketika kita memunculkan 2, kita dapat melihat bahwa nilai minimumnya adalah 2 sekarang dan jika ini muncul maka kita perlu memperbarui nilai minimum menjadi 3.
Point1:
Sekarang jika Anda mengamati dengan seksama kita perlu menghasilkan nilai min = 3 dari keadaan tertentu ini [2, nilai minimum = 2]. atau jika Anda menggunakan tumpukan, kami perlu menghasilkan nilai minimum = 7 dari keadaan tertentu ini [3, nilai minimum = 3] atau jika Anda lebih depper dalam tumpukan maka kita perlu menghasilkan nilai minimum = 8 dari keadaan tertentu ini [7, nilai minimum = 7]
Apakah Anda melihat sesuatu yang sama dalam semua 3 kasus di atas, nilai yang perlu kita hasilkan bergantung pada dua variabel yang keduanya sama. Benar. Mengapa ini terjadi karena ketika kita mendorong beberapa elemen lebih kecil dari nilai min saat ini, maka pada dasarnya kita mendorong elemen itu ke dalam tumpukan dan memperbarui nomor yang sama di nilai min juga.
Point2:
Jadi pada dasarnya kita menyimpan duplikat dari nomor yang sama sekali dalam tumpukan dan sekali dalam variabel nilai kecil. Kita perlu fokus untuk menghindari duplikasi ini dan menyimpan data yang berguna dalam tumpukan atau nilai minimum untuk menghasilkan nilai minimum sebelumnya seperti yang ditunjukkan dalam KASUS di atas.
Mari kita fokus pada apa yang harus kita simpan dalam tumpukan ketika nilai yang akan disimpan dalam push kurang dari nilai minmum. Beri nama variabel ini y, jadi sekarang tumpukan kita akan terlihat seperti ini:
6 , minvalue=2
y1 , minvalue=2
5 , minvalue=3
y2 , minvalue=3
9 , minvalue=7
y3 , minvalue=7
8 , minvalue=8
Saya telah mengganti namanya menjadi y1, y2, y3 untuk menghindari kebingungan bahwa semuanya akan memiliki nilai yang sama.
Point3:
Sekarang Mari kita coba mencari beberapa batasan di atas y1, y2 dan y3. Apakah Anda ingat kapan tepatnya kita perlu mengupdate minvalue saat melakukan pop (), hanya ketika kita telah memunculkan elemen yang sama dengan minvalue. Jika kita memunculkan sesuatu yang lebih besar dari nilai min, maka kita tidak perlu memperbarui nilai min. Jadi untuk memicu pembaruan nilai min, y1, y2 & y3 harus lebih kecil daripada nilai min yang sesuai. [Kami menghindari persamaan untuk menghindari duplikasi [Titik2]] sehingga batasannya adalah [y <nilai min].
Sekarang mari kembali ke mengisi y, kita perlu menghasilkan beberapa nilai dan meletakkan y pada saat mendorong, ingat. Mari kita ambil nilai yang akan datang untuk mendorong menjadi x yang kurang dari nilai prevMinvalue, dan nilai yang sebenarnya akan kita dorong dalam tumpukan menjadi y. Jadi satu hal yang jelas bahwa newMinValue = x, dan y <newMinvalue.
Sekarang kita perlu menghitung y (ingat y bisa berupa angka apa saja yang kurang dari newMinValue (x) jadi kita perlu mencari beberapa angka yang bisa memenuhi batasan kita) dengan bantuan prevMinvalue dan 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].
Jadi pada saat menekan x jika kurang dari prevMinvalue maka kami mendorong y [2 * x-prevMinValue] dan memperbarui newMinValue = x.
Dan pada saat pop jika stack berisi sesuatu yang kurang dari minValue maka itulah pemicu kami untuk memperbarui minVAlue. Kita harus menghitung prevMinValue dari curMinValue dan y. y = 2 * curMinValue - prevMinValue [Terbukti] prevMinVAlue = 2 * curMinvalue - y.
2 * curMinValue - y adalah angka yang perlu kita perbarui sekarang ke prevMinValue.
Kode untuk logika yang sama dibagikan di bawah ini dengan kompleksitas O (1) waktu dan O (1) ruang.
// 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;
}