题目描述
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) —— 将元素 x 推入栈中。
- pop() —— 删除栈顶的元素。
- top() —— 获取栈顶元素。
- getMin() —— 检索栈中的最小元素。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
说明:
pop、top 和 getMin 操作总是在 非空栈 上调用。
题目链接: https://leetcode-cn.com/problems/min-stack/
思路1
这个题的难点在于用常数时间获取最小值,其他的操作都可以使用常规的栈实现。为了在常数时间内获得最小值,我们除了存储数据的栈 dataStack 外,还需要一个辅助栈 helperStack,helperStack 存储 将数据压入到 dataStack 的过程中遇到的最小元素。算法步骤如下:
将 x 入栈:
- 将 x 压入 dataStack,如果 helperStack 为空或者 x <= helperStack.top(),那么将 x 压入 helperStack;
出栈:
- 如果 dataStack 的栈顶元素等于 helperStack 的栈顶元素,则两个栈均出栈;
- 否则,只将 dataStack 的栈顶元素出栈;
获取最小值:
- 返回 helperStack 的栈顶元素即可。
例如,我们将 [-2, 0, -3] 依次压入到栈中:
- 压入 -2: dataStack = [-2], helperStack = [-2];
- 压入 0:dataStack = [-2, 0],因为 0 大于 helperStack 的栈顶元素 -2,所以不将 0 压入 helperStack,helperStack 依旧是 [-2]
- 压入 -3:dataStack = [-2, 0, -3], 因为 -3 小于等于 helperStack 的栈顶元素 -2,所以将 -3 压入到 helperStack,此时 helperStack = [-2, -3]
模拟获取最小值以及出栈过程:
- 获取最小值:helperStack.top() == -3,就是最小值;
- 出栈:此时 dataStack 为 [-2, 0],因为出栈元素 -3 等于 helperStack 的栈顶元素,所以将 helperStack 的栈顶元素 -3 也出栈;
- 获取最小值:helperStack.top() == -2,就是最小值。
代码如下:
class MinStack {
stack<int> dataStack, helpStack;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
dataStack.push(x);
if(helpStack.empty() || x<=helpStack.top()){
helpStack.push(x);
}
}
void pop() {
if(dataStack.top()==helpStack.top()){
dataStack.pop();
helpStack.pop();
}else{
dataStack.pop();
}
}
int top() {
return dataStack.top();
}
int getMin() {
return helpStack.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();
*/
思路2
使用一个栈,栈同时存放当前元素和当前的最小元素,可以使用pair
来包装起来,栈的定义为stack<pair<int, int>> s
,pair 的第一个元素是当前入栈元素,pair 的第二个元素是当前的最小值。入栈的时候需要进行判断,假设入栈元素为 x,入栈时:
- 如果 s 为空,则 s.push(make_pair(x, x));
- 否则,将 x 和 s.top().second(当前栈的最小元素)比较:
- 如果 x <= s.top().second,则 s.push(make_pair(x, x));
- 否则,s.push(make_pair(x, s.top().second));
这样入栈的话,s.top().second
就是当前的最小元素。
代码如下:
class MinStack {
stack<pair<int, int>> s;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
if(s.empty()){
s.push(make_pair(x, x));
}else{
int curMin = s.top().second;
if(x<=curMin){
s.push(make_pair(x, x));
}else{
s.push(make_pair(x, curMin));
}
}
}
void pop() {
s.pop();
}
int top() {
return s.top().first;
}
int getMin() {
return s.top().second;
}
};
/**
* 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();
*/