题目描述
设计一个支持push,pop,top等操作并且可以在O(1)时间内检索出最小元素的堆栈。
- push(x)–将元素x插入栈中
- pop()–移除栈顶元素
- top()–得到栈顶元素
- getMin()–得到栈中最小元素
样例
MinStack minStack = new MinStack();
minStack.push(-1);
minStack.push(3);
minStack.push(-4);
minStack.getMin(); --> Returns -4.
minStack.pop();
minStack.top(); --> Returns 3.
minStack.getMin(); --> Returns -1.
算法
(单调栈) $O(1)$
用一个栈 stk 维护基本的栈操作,同时需要维护一个单调栈 min_stk,用来返回栈中的最小值
push(x)
: 压入 x 到基本栈 stk,同时判断单调栈 min_stk 是否为空或当前元素 x 是否小于等于当前栈顶元素,如果是,同样将 x 压入到单调栈中这里为什么相等也要入栈,是因为在 pop 的时候我们判断的条件就是如果两个栈顶相等,min_stk 也要弹出元素,所以 min_stk 中要压入 x,否则如果 stk 的最小值为有多个相等的值 x,那么 stk 和 min_stk 都弹出 x 之后,此时 stk 的最小值仍然是 x,但 min_stk 的栈顶一定小于 x,与答案不符,所以必须要压入 x
pop()
: 在基本栈 stk 弹出之前,需要判断 stk 的栈顶和 min_stk 的栈顶是否相等,如果相等 min_stk 也要弹出栈顶top()
: stk.top()getMin()
: min_stk.top()
时间复杂度
四个操作都只有常数次入栈出栈操作,所以时间复杂度是 $O(1)$
C++ 代码
class MinStack {
public:
stack<int> stk, min_stk;
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stk.push(x);
if (!min_stk.size() || min_stk.top() >= x) min_stk.push(x);
}
void pop() {
if (stk.top() == min_stk.top()) min_stk.pop();
stk.pop();
}
int top() {
return stk.top();
}
int getMin() {
return min_stk.top();
}
};
/**
* 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();
*/