title | toc | date | tags | top | |||
---|---|---|---|---|---|---|---|
155. Min Stack |
false |
2017-10-10 |
|
155 |
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.
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
首先想到,在栈里面设置一个min变量,当栈push一个数时,和min比较,如果比他大,min不变,比他小,min更新。但是这样,pop了min之后就没有了min的数据了……
也就是说,min这个数据,不只要维护当前的最小值,还要有之前的栈里面的数据信息。那么min这个数据应该和栈同步增长数据和减少数据,这样自然想到min应该也是一个栈。而且这个栈的栈顶应该是整个栈的最小值,这样,才能取出来。于是,很自然的想到,在datastack进行push(x)操作的时候,minstack要取出他的栈顶元素(最小值min),和$x$进行比较,如果$x>$min, minstack就push(min),否则,push(x);
class MinStack {
private Stack<Integer> numStack, minStack;
public MinStack() {
numStack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
numStack.push(x);
if (minStack.isEmpty() || x < minStack.peek())
minStack.push(x);
else minStack.push(minStack.peek());
}
public void pop() {
if (numStack.isEmpty())
throw new IllegalArgumentException("Stack is empty");
numStack.pop();
minStack.pop();
}
public int top() {
return numStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
一种优化的办法,就是每次push(x)
的时候,都比较min和$x$的大小,如果$x>$min, minstack不进行操作;否则,对于minstack进行push(x)
的操作。这样相应的pop()
操作也要改变。每次pop()
的时候,都要检查pop()
出来的值$x$是否大于min:如果是,则minstack不进行操作,如果$x=$min,那么对minstack进行pop()
操作。这样,对于minstack的存储空间有一定的降低。
class MinStack {
private Stack<Integer> numStack, minStack;
public MinStack() {
numStack = new Stack<>();
minStack = new Stack<>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int x) {
// 注意:是<=,而不是<。当最小元素重复的时候,需要入栈
if (x <= minStack.peek()) minStack.push(x);
numStack.push(x);
}
public void pop() {
// 特别注意:使用equals而不是==
if (numStack.pop().equals(minStack.peek()))
minStack.pop();
}
public int top() {
return numStack.peek();
}
public int getMin() {
return minStack.peek();
}
}