题目链接:155. Min Stack 最小栈

解题思路:
使用两个栈来实现本题要求,一个栈用于保存所有元素,这个栈与普通栈没有区别,记为stackData;另一个栈用于保存每一步的最小值,记为stackMin

  1. push(x)操作 - 将元素 x 推入栈中。
    当前元素记为newNum,压入stackData。然后判断stackMin是否为空:
    • stackMin为空,也入栈;
    • stackMin不为空,则将newNumstackMin栈顶元素比较。
      newNum <= stackMin栈顶元素,则newNum压入stackMin
      否则stackMin不执行操作。
  2. pop()操作 - 删除栈顶的元素。
    先将stackData进行出栈,并保存其栈顶元素,记为stackDataTop
    由设计思路可知,stackMin的栈顶一定小于等于stackData的栈顶,且stackMin从栈底到栈顶依次减小,stackMin栈顶元素也是全部数据的最小值
    stackDataTop == stackMin栈顶stackMin也需进行出栈操作。注意:这一步是必须进行判断的。这是因为:若最后压入栈的元素是最小的,若只对stackData进行出栈而不对stackMin进行出栈,进行getMin()操作时,从stackMin得到的最小值会是错误的。
  3. top()操作 - 获取栈顶元素。
    直接对stackData进行peek()操作即可。
  4. getMin()操作 - 检索栈中的最小元素。
    stackMin的栈顶元素即是最小元素,对stackMin进行peek()操作即可。

代码实现:

class MinStack {
    // 用于存储所有数据
    private Stack<Integer> stackData;
    // 用于存储每一步的最小值
    private Stack<Integer> stackMin;

    /** initialize your data structure here. */
    public MinStack() {
        this.stackData = new Stack<Integer>();
        this.stackMin = new Stack<Integer>();
    }
    
    public void push(int x) {
        // 若stackMin为空,也一并入栈
        if (this.stackMin.isEmpty()) {
            this.stackMin.push(x);
        } 
        // 若当前元素小于stackMin栈顶元素,stackMin入栈
        else if (x <= this.stackMin.peek()) {
            this.stackMin.push(x);
        }

        this.stackData.push(x);
    }
    
    public void pop() {
        if (this.stackData.isEmpty()) {
            throw new RuntimeException("Stack is empty!");
        }
        int stackDataTop = this.stackData.pop();
        // 如果stackData栈顶元素与stackMin栈顶元素相等,stackMin也要进行出栈
        if (stackDataTop == this.stackMin.peek()) {
            this.stackMin.pop();
        }
    }
    
    public int top() {
        return this.stackData.peek();
    }
    
    public int getMin() {
        return this.stackMin.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(); */

提交结果:
执行用时:7ms;内存消耗:40MB;战胜91.71%。


参考:左程云《程序员代码面试指南:IT名企算法与数据结构题目最优解》