解题思路:

  1. 和一般栈的区别是需要记录栈存放的最小值,当栈元素更新的时候需要更新这个最小值
  2. 一开始想到的是使用一个链表进行记录,但是这样的话需要将栈元素中存放的元素变为节点地址,然后维护节点的顺序(本质上可以实现,但是过于低效)
  3. 2方法不可行的时候,需要注意到栈本身的特性,最后入栈的元素会先出栈,也就是说,如果当前入栈的元素如果不是最小的值,那么代表最小的值是先于该元素入栈的,这样该元素出栈入栈其实是不会更新最小值的。
  4. 基于第三点的认知,因为入栈的元素可能存在多个相等值,比如入栈了2/0/0/0/-1,当-1 pop 0 pop 0 pop时,最小值还是0,也就是说最小值有几个,我们就需要保存几个。
  5. 基于上述思想归纳,可以使用一个辅助记录最小元素的栈。
  6. 入栈,当入栈元素<=当前最小元素的时候,在正常栈和最小栈同时入栈;当入栈元素>当前最小元素的时候,只入栈正常栈。
  7. 出栈,当出栈元素==当前最小元素时,正常栈和最小栈同时出栈;当出栈元素>当前最小元素时,仅正常栈出栈。
class MinStack {

    // 存元素栈
    int[] stack;
    int top = -1;

    // 
    int[] minStack;
    int minIndex = -1;
    
    /** initialize your data structure here. */
    public MinStack() {
        stack = new int[20000];
        minStack = new int[20000];
    }
    
    public void push(int x) {
        // 注意数组初始化的值为0,用length获取的是初始化数组的长度,实际使用元素的长度需要使用标识记录
        if (minIndex == -1) {
            minStack[++minIndex] = x;
        } else {
            if(x <= minStack[minIndex]) {
                minStack[++minIndex] = x;
            }
        }
        stack[++top]= x;
    }
    
    public void pop() {
        int x = stack[top--];
        if (x == minStack[minIndex]) {
            minIndex --;
        }
    }
    
    public int top() {
        return stack[top];
    }
    
    public int min() {
        return minStack[minIndex];
    }
}

Q.E.D.


每一个平凡的日常都是连续的奇迹