題目描述
定義棧的數據結構,請在該類型中實現一個能夠得到棧最小元素的min函數。調用min、push及pop的時間複雜度都是O(1)。
方法一
考慮使用兩個棧,一個數據棧(就是普通的棧),實現棧的push、pop等操作;另一個輔助棧用來存放每次棧操作時(包括入棧和出棧)棧中最小元素。
輔助棧的操作:棧頂元素爲當前棧中的最小元素
- 要獲取當前棧中最小元素,只需要返回棧頂元素即可;
- 每次執行push操作,檢查push的元素與棧頂元素的大小關係。將較小的元素push到輔助棧中。
- 當執行pop操作的時候,將輔助棧中的棧頂元素pop出去。
實例:
代碼
class Solution {
public:
stack<int> data;
stack<int> minNum;
void push(int value) {
data.push(value);
if( minNum.empty() )
minNum.push(value);
else
minNum.push( minNum.top()<value?minNum.top():value );
}
void pop() {
// assert( !data.empty() && !minNum.empty() );
data.pop();
minNum.pop();
}
int top() {
return data.top();
}
int min() {
return minNum.top();
}
};
簡單優化:對於輔助棧的操作,每次執行push操作時,檢查push的元素是否小於或等於輔助棧棧頂元素。如果是,則也push該元素到輔助棧中。當執行pop操作的時候,檢查pop的元素是否與當前最小值相等。如果相同,則需要將該元素從輔助棧中pop出去。其餘情況對於輔助棧可以不做修改。方法二
解法利用存儲差值而不需要輔助棧,方法比較巧妙。該方法需要額外使用佔用一個空間存儲當前棧中的最小值,將最小值一直儲存在棧頂。- 當需要push進一個新值value時,先將最小值pop出來,在棧中壓入value與當前棧中最小元素的差值,然後比較value與當前棧中最小元素大小,將它們中間的較小值壓入棧。
- 執行min()函數時,直接返回棧頂元素即可。
- 執行top()函數時,返回棧頂兩個元素的和即可。
- 執行pop()函數時,先pop出棧頂的兩個值,這兩個值分別是當前棧中最小值min和最後壓入的元素與棧中最小值的差值diff,因爲pop()函數需要把最後存入的值刪除,所以只需要考慮pop後的最小值min是多少,並將其壓入棧中。如果diff<0,則表示最後壓入棧的元素是最小的元素,因此只需將min-diff壓入棧中,min-diff就是當前元素彈出後,棧中剩下元素的最小值。而如果diff>=0且棧不爲空,則表示當前值不是最小值,所以需要在棧中壓入最小值min。
clear(): [ ]
push(3): [3 3]
push(4): [3 1 3]
push(2): [3 1 -1 2]
push(5): [3 1 -1 3 2]
push(1): [3 1 -1 3 -1 1]
push(1): [3 1 -1 3 -1 0 1]
push(6): [3 1 -1 3 -1 0 5 1]
push(7): [3 1 -1 3 -1 0 5 6 1]
min() --> 1; pop() --> 7: [3 1 -1 3 -1 0 5 1]
min() --> 1; pop() --> 6: [3 1 -1 3 -1 0 1]
min() --> 1; pop() --> 1: [3 1 -1 3 -1 1]
min() --> 1; pop() --> 1: [3 1 -1 3 2]
min() --> 2; pop() --> 5: [3 1 -1 2]
min() --> 2; pop() --> 2: [3 1 3]
min() --> 3; pop() --> 4: [3 3]
min() --> 4; pop() --> 3: [ ]
代碼
class Solution {
public:
stack<int> data;
void push(int value) {
if( data.empty() )
{
data.push(value);
data.push(value);
return;
}
int min = data.top();
data.pop();
if( min <= value )
{
data.push(value-min);
data.push(min);
return;
}
else
{
data.push(value-min);
data.push(value);
return;
}
return;
}
void pop() {
int min = data.top();
data.pop();
if( data.top() >= 0 )
{
data.pop();
data.push(min);
return;
}
else
{
int temp = data.top();
data.pop();
data.push(min-temp);
}
return;
}
int top() {
int min = data.top();
data.pop();
int res = data.top()+min;
data.push(min);
return res;
}
int min() {
return data.top();
}
};
參考文獻:
https://www.cnblogs.com/javawebsoa/archive/2013/05/21/3091727.html
https://blog.csdn.net/sgbfblog/article/details/7752878