设计包含min函数的栈
2019獨角獸企業重金招聘Python工程師標準>>>
題目: 設計一個棧,使得PUSH、POP以及GetMin(獲取棧中最小元素)能夠在常數時間內完成。
分析: 很剛開始很容易想到一個方法,那就是額外建立一個最小堆保存所有元素,這樣每次獲取最小元素只需要O(1)的時間。但是這樣的話,PUSH和POP操作就需要O(lgn)的時間了(假定棧中元素個數為n),不符合題目的要求。 那么用1個輔助棧如何呢?
解法: 使用一個輔助棧來保存最小元素,這個解法簡單不失優雅。設該輔助棧名字為minimum stack,其棧頂元素為當前棧中的最小元素。這意味著 要獲取當前棧中最小元素,只需要返回minimum stack的棧頂元素即可。 每次執行push操作,檢查push的元素是否小于或等于minimum stack棧頂元素。如果是,則也push該元素到minimum stack中。 當執行pop操作的時候,檢查pop的元素是否與當前最小值相等。如果相同,則需要將改元素從minimum stack中pop出去。 代碼: [cpp] view plain copy struct StackGetMin {
void push(int x) {
elements.push(x);
if (minStack.empty() || x <= minStack.top()) //push的元素小于當前minStack的最小元素,則push到minStack中
minStack.push(x);
}
bool pop() {
if (elements.empty()) return false;
if (elements.top() == minStack.top()) //如果原始棧棧頂元素與minStack棧頂元素相同,則將該元素也從minStack中pop出去。
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;
};
實例: 假定有元素3, 2, 5, 4, 2, 1依次入棧,則原始棧中元素為(1), 輔助棧中元素為(2) 1
2
4 1 5 2 2 2 3 3 (1) (2) 這樣,第1次pop時,1從兩個棧都pop出去;第2次pop時,2從兩個棧都pop出去;第3次pop,元素4從原始棧pop出去,輔助棧不用pop;第4次pop,元素5從原始棧pop出去,輔助棧不需pop;第5次pop,元素2從兩個棧pop出去;第6次pop,元素3從兩個棧都pop出去。我們可以發現,每次push或者pop后,輔助棧的棧頂元素總是當前棧的最小元素。
另一解法(不用輔助棧) 另外一種解法利用存儲差值而不需要輔助棧,方法比較巧妙。其中需要說明的幾點: push(int elem)函數在棧中壓入當前元素與當前棧中最小元素的差值,然后通過比較當前元素與當前棧中最小元素大小,并將它們中間的較小值壓入。 pop()函數執行的時候,先pop出棧頂的兩個值,這兩個值分別是當前棧中最小值min和最后壓入的元素與棧中最小值的差值diff。如果diff<0,則表示最后壓入棧的元素是最小的元素,因此只需將min-diff壓入棧中,并將min值返回即可。min-diff就是當前元素彈出后,棧中剩下元素的最小值。而如果diff>=0且棧不為空,則表示當前值不是最小值,所以需要在棧中壓入最小值min并將diff+min返回;如果棧為空,則表示已經是最后一個數字,直接返回min即可。 [cpp] view plain copy stack<int> s;
void push(int elem)
{
if (s.empty()) {
s.push(elem);
s.push(elem);
} else {
int min = s.top();
s.pop();
s.push(elem - min);
s.push(elem < min ? elem : min);
}
}
int pop()
{
int min = s.top();
s.pop();
int diff = s.top();
s.pop();
if (diff < 0) {
s.push(min - diff);
return min;
} else {
if (!s.empty()) {
s.push(min);
return diff + min;
}
return min;
}
}
int min()
{
int min = s.top();
return 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: [ ]
參考資料: 設計包含min的棧另解
轉載于:https://my.oschina.net/u/2307114/blog/844367
總結
以上是生活随笔為你收集整理的设计包含min函数的栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios 处理WKContentView的
- 下一篇: UVA10780:Again Prime