155、最小栈

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

  • 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.

提示:

  • poptopgetMin 操作总是在 非空栈 上调用。

本题其实没有看上去的那么简单,如果你没有想到辅助栈的思路的话。
由于本题要求是在常数时间内检索到最小元素,而一般的栈是不满足这个功能的,一般就能想到肯定是用空间换时间。
很自然想到用一个数记录最小值,如果入的是比这个最小值小那就更新最小值,到时候返回最小值就是返回这值。但是这个思路没有想到如果当你出栈出了最小值怎么办,难道还要记录第二小,那万一出了第二小的值又怎么办,很快将这个思路否决,那应该如何记录最小值呢,直观上来说可以用一个排序的数组,每次插入一个数就排序,然后返回最小值,这个方法可以做,但是不好,最好的思路还是用辅助栈。

我们可以用一个最小栈来记录最小值,当栈是空或者最小栈的栈顶大于要插入的数,我们插入最小栈,这样最小栈的值一定是最小的,如果大于最小栈的栈顶是不会插入最小栈的。只会插入原本的栈中,那么我们就可以做出来本题了。

本题的难点其实在于我们是否想到了用辅助栈的思路,一旦想到了,那么整道题就迎刃而解了。

注意在比较两个对象是否相同的时候应该用equal方法,我之所以可以直接用==来判等,是由于我将min的Integer自动装箱转换为int。

代码如下:

class MinStack {
    
    Stack stack;
    Stack min;
    /** initialize your data structure here. */
    public MinStack() {
        stack = new Stack<>();
        min = new Stack<>();
    }
    public void push(int x) {
        stack.push(x);
        if (min.isEmpty() || min.peek() >= x){
            min.push(x);
        }
    }
    
    public void pop() {
        int top = min.peek();
        if( top == stack.peek()){
            min.pop();
        }
        stack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return min.peek();
    }
}

/**
 * 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();
 */

你可能感兴趣的:(155、最小栈)