題目鏈接:155. Min Stack 最小棧
解題思路:
使用兩個棧來實現本題要求,一個棧用於保存所有元素,這個棧與普通棧沒有區別,記爲stackData
;另一個棧用於保存每一步的最小值,記爲stackMin
。
push(x)
操作 - 將元素 x 推入棧中。
當前元素記爲newNum
,壓入stackData
。然後判斷stackMin
是否爲空:- 若
stackMin
爲空,也入棧; - 若
stackMin
不爲空,則將newNum
與stackMin
棧頂元素比較。
若newNum <= stackMin棧頂元素
,則newNum
壓入stackMin
;
否則stackMin
不執行操作。
- 若
pop()
操作 - 刪除棧頂的元素。
先將stackData
進行出棧,並保存其棧頂元素,記爲stackDataTop
。
由設計思路可知,stackMin
的棧頂一定小於等於stackData
的棧頂,且stackMin
從棧底到棧頂依次減小,stackMin
棧頂元素也是全部數據的最小值。
若stackDataTop == stackMin棧頂
,stackMin
也需進行出棧操作。注意:這一步是必須進行判斷的。這是因爲:若最後壓入棧的元素是最小的,若只對stackData
進行出棧而不對stackMin
進行出棧,進行getMin()
操作時,從stackMin
得到的最小值會是錯誤的。top()
操作 - 獲取棧頂元素。
直接對stackData
進行peek()
操作即可。getMin()
操作 - 檢索棧中的最小元素。
stackMin
的棧頂元素即是最小元素,對stackMin
進行peek()
操作即可。
代碼實現:
class MinStack {
// 用於存儲所有數據
private Stack<Integer> stackData;
// 用於存儲每一步的最小值
private Stack<Integer> stackMin;
/** initialize your data structure here. */
public MinStack() {
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
public void push(int x) {
// 若stackMin爲空,也一併入棧
if (this.stackMin.isEmpty()) {
this.stackMin.push(x);
}
// 若當前元素小於stackMin棧頂元素,stackMin入棧
else if (x <= this.stackMin.peek()) {
this.stackMin.push(x);
}
this.stackData.push(x);
}
public void pop() {
if (this.stackData.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
int stackDataTop = this.stackData.pop();
// 如果stackData棧頂元素與stackMin棧頂元素相等,stackMin也要進行出棧
if (stackDataTop == this.stackMin.peek()) {
this.stackMin.pop();
}
}
public int top() {
return this.stackData.peek();
}
public int getMin() {
return this.stackMin.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
提交結果:
執行用時:7ms;內存消耗:40MB;戰勝91.71%。
參考:左程雲《程序員代碼面試指南:IT名企算法與數據結構題目最優解》