跳转至

155. Min Stack

Leetcode Stack Design

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();
    }
}