题目:
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- getMin() -- Retrieve the minimum element in the stack.
Attention: 等于最小栈栈顶的元素也要push进最小栈,可能有多个相等的最小值。
复杂度:O(1)
AC Code:
class MinStack {
public:
//维护一个最小栈,这样在常量时间返回栈的最小值。
void push(int x) {
s.push(x);
//小于等于都要压栈
if(mins.empty() || (x <= mins.top())){
mins.push(x);
}
}
void pop() {
int pop = s.top();
s.pop();
if(pop == mins.top()){
mins.pop();
}
}
int top() {
return s.top();
}
int getMin() {
return mins.top();
}
private:
stack<int> s;
stack<int> mins;
};
入栈操作:真正入栈的是值x和pre_min的差值,然后更新最小值min,等到最新的min值。
出栈操作:由于入栈操作可能需要更新最小值min,所以出栈操作会影响到剩余元素的最小值,需要求出pre_min。根据入栈时,min值是否发生改变,我们来判断出栈时min值是否需要更新。若入栈时,min未发生更新,即top()>=0时,直接删除栈顶元素。如果入栈时,min值发生改变,即top()<0时,此时有x-pre_min=top(),故可求pre_min=min(x)- top()。
取栈顶元素操作:由于栈顶存储差值,所以需要计算相应的值x。要么是min,要么是min+top()。判断条件是,在入栈时min是否改变,若改变,即top()<0,此时min等于x,返回min;如果没有改变,即top()>=0,返回min+top()。
Attention: 考虑可能产生正负数,使用long类型。
AC Code:
class MinStack
{
static class Element
{
final int value;
final int min;
Element(final int value, final int min)
{
this.value = value;
this.min = min;
}
}
final Stack<Element> stack = new Stack<>();
public void push(int x) {
final int min = (stack.empty()) ? x : Math.min(stack.peek().min, x);
stack.push(new Element(x, min));
}
public void pop()
{
stack.pop();
}
public int top()
{
return stack.peek().value;
}
public int getMin()
{
return stack.peek().min;
}
}
Code: long long 类型超出leetcode 限制
class MinStack {
public:
void push(int x) {
if(s.empty()){
//第一个值需要push 0(0的Long), 记得stack存储的是和当前上一个最小值的差值。push(x -x)
s.push(0L);
min = x;
}
else{
s.push(x - min);
if(x < min) min = x;
}
}
void pop() {
long long tmp = s.top();
s.pop();
if(tmp < 0) min = min - tmp;
}
int top() {
long long tmp = s.top();
if(tmp > 0){
return (int)(min + tmp);
}
else{
return (int)min;
}
}
int getMin() {
return (int)min;
}
private:
stack<long long> s;
long long min;
};