请设计一个栈,除了常规栈支持的pop与push函数以外,还支持min函数,该函数返回栈元素中的最小值。执行push、pop和min操作的时间复杂度必须为O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路:
利用一个min变量标记当前的最小栈内元素。压栈时,如果最小元素发生变更,就把当前最小元素也进行压栈,标记这一次的最小元素变更情况。出栈时,如果遇到当前最小值与栈顶元素相同的情况,就连着这个元素一起弹出,并将当前最小值更新为这个元素的下一个元素。理论上这个方式比双栈更省空间。
class MinStack {
/**
* initialize your data structure here.
*/
Stack stack;
//将最小值初始化为整型的最大值
int min = Integer.MAX_VALUE;
public MinStack() {
//初始化一个栈
stack = new Stack();
}
public void push(int x) {
//当min==x时要重新存一下最小值,否则最小的值min会出现两次
//一次是当前的min,一次是维护当前min的第一个值
//如果if的条件改为min>x,则会影响pop()出栈的逻辑
if (min >= x) {
stack.push(min);
//维护最小值序列的第一个值(最小),并赋值给min
min = x;
}
//入栈
stack.push(x);
}
public void pop() {
//栈为空时返回空即可
if (stack.isEmpty()) {
return;
}
//长度为1时其实只存了min的初值,没有存其他值
if (stack.size() == 1) {
min = Integer.MAX_VALUE;
//min==top()说明栈顶元素是一段维护最小值序列的第一个值(即最小值)
} else if (min == top()) {
//先把这个最小值弹出
stack.pop();
//此时的栈顶元素是之前入栈时额外存入的最小值
min = top();
}
//出栈
stack.pop();
}
public int top() {
//此处直接调用java中与stack相关的API即可
return (int)stack.peek();
}
public int getMin() {
//min可以随时返回,达到了时间复杂度必须为O(1)的要求
return min;
}
}
/**
* 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();
*/