需要更好的閱讀的體驗請移步 👉 小牛肉的個人博客 👈
題目描述
定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。
注意:保證測試中不會當棧爲空的時候,對棧調用pop()或者min()或者top()方法。
算法思想
該題難點在於最小元素min函數的寫法,使用雙棧法
使用一個棧按照大小順序存儲每次當前所有元素的最小值
比如:
stack1是普通的棧,完成正常操作。用stack2順序存儲最小值元素
-
初始狀態
stack1 :
stack2: -
壓入8:stack2爲空,則直接壓入
stack1 : 8
stack2: 8 -
壓入 6:6 小於 stack2 的當前棧頂元素 8,則直接壓入
stack1 : 8 6
stack2: 8 6 -
壓入 5:5 小於 stack2 的當前棧頂元素 6,則直接壓入
stack1 : 8 6 5
stack2: 8 6 5 -
壓入 9:9 大於 stack2 的當前棧頂元素 5,不壓入stack2
stack1 : 8 6 5 9
stack2: 8 6 5 -
壓入 4:4 小於 stack2 的當前棧頂元素 5,則直接壓入
stack1 : 8 6 5 9 4
stack2: 8 6 5 4
可以看到,當前棧頂的最小元素就是stack2的棧頂元素 4
-
出棧1次:stack2的棧頂元素4(當前所有元素的最小值)和stack1的棧頂元素 4 相同,則一併彈出,表示最小元素被更新了
stack1 : 8 6 5 9
stack2: 8 6 5
則當前棧中的最小值變爲5 -
出棧2次:stack2的棧頂元素5(當前所有元素的最小值)和 stack1的棧頂元素不同,則只需彈出stack1的棧頂即可,說明當前所有元素的最小值不會因爲9的彈出而改變,還是stack2的棧頂元素5
stack1 : 8 6 5
stack2: 8 6 5
則當前棧中的最小值還是5
具體代碼
- C++
class Solution {
public:
//stack2用來有序排列stack1中的值,保證值從小到大排列(棧尾-》棧頂)
// 保證stack2中的棧頂始終是當前棧的最小值
stack<int> stack1, stack2;
void push(int value) {
stack1.push(value);
if(stack2.empty()) //如果順序棧爲空,則直接壓入
stack2.push(value);
else if(value <= stack2.top()) //如果要壓入的值小於當前順序棧的棧頂,則壓入
stack2.push(value);
}
void pop() {
// 如果要彈出的值和順序棧的棧頂元素相同,則一併彈出
// 表示原先棧中的最小值隨着本次彈出操作,原先的最小值被彈出來了
// 彈出原先的最小值後,當前順序棧stack2的棧頂仍然是當前棧的最小值
if(stack1.top() == stack2.top())
stack2.pop();
stack1.pop();
}
int top() {
return stack1.top();
}
int min() {
return stack2.top();
}
};
- Java
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
if(stack2.empty())
stack2.push(node);
else if(node <= stack2.peek())
stack2.push(node);
}
public void pop() {
if(stack1.peek() == stack2.peek())
stack2.pop();
stack1.pop();
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}