LeetCode-剑指 Offer 30. 包含min函数的栈
- 1. 问题描述
- 2. 解析
- 3. 考答案

1. 问题描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();   --> 返回 0.
minStack.min();   --> 返回 -2.提示:
 各函数的调用总次数不超过 20000 次
2. 解析
通过上面的描述我觉得直接用O(1)能解决问题吗?
 不得判断所有栈里面的数据从小到大排列一下。
 后来看了题解才发现我理解错误了。
 题目的要求就是压进去的数据顺序不变,
 只是每次栈里面的最小数是有顺序的。
 这里面不需要使用两个栈,
 有一个最小值变量维护,
 每次压进去保存最小值,
 然后也把最小值压进去,
 就是每次压进去两个值:最小值和当前值。
 然后弹出的时候需要弹出两个值:当前值和最小值。
 注意:压入最小值和当前值的顺序不能变!

3. 考答案
class MinStack {
    private Stack<Integer> stack;
    private Integer min = Integer.MAX_VALUE;
    /** 初始化*/
    public MinStack() {
        stack = new Stack<>();
    }
    /**
     * 压入栈
     */
    public void push(int x) {
        // 上来先把最小值压进去,保证最顶端的值是最小值
        stack.push(min);
        // 判断新值是否是最小的
        if (x < min) {
            min = x;
        }
        // 然后把新值压进去
        stack.push(x);
    }
    /**
     * 正常弹出即可
     */
    public void pop() {
        // 注意要把新值弹出去
        stack.pop();
        // 接下来得到的是最小值
        min = stack.peek();
        // 因为之前我们先把最小值压进去,所以要弹出两次
        stack.pop();
    }
    /**
     * 获取栈顶的数据
     */
    public int top() {
        return stack.peek();
    }
    /**
     * 获取最小值
     */
    public int min() {
        return min;
    }
    public static void main(String[] args) {
        // 输入指令那一行数据如:["MinStack","push","push","push","min","pop","top","min"]
        Scanner scanner = new Scanner(System.in);
        String inputStr = scanner.next();
        // 去头去尾,替换“并处理成: MinStack,push,push,push,min,pop,top,min
        inputStr = inputStr.substring(1, inputStr.length() - 1).replaceAll("\"", "");
        String[] commends = inputStr.split(",");
        // 输入代码对应的值:[[],[-2],[0],[-3],[],[],[],[]]
        String valueStr = scanner.next();
        // 去头去尾即可:[],[-2],[0],[-3],[],[],[],[]
        valueStr = valueStr.substring(1, valueStr.length() - 1);
        String[] values = valueStr.split(",");
        MinStack minStack = null;
        // 存放最终的结果
        StringBuilder result = new StringBuilder();
        result.append("[");
        for (int i = 0; i < commends.length; i++) {
            String commend = commends[i];
            String value = values[i];
            // 对应处理指令
            switch (commend) {
                // 初始化
                case "MinStack":
                    minStack = new MinStack();
                    result.append("null,");
                    break;
                // 入栈
                case "push":
                    // 去头去尾,拿到中括号里面数字
                    String num = value.substring(1, value.length() - 1);
                    minStack.push(Integer.parseInt(num));
                    result.append("null,");
                    break;
                // 获取最小值
                case "min":
                    int min = minStack.min();
                    result.append(min+",");
                    break;
                // 出栈
                case "pop":
                    minStack.pop();
                    result.append("null,");
                    break;
                // 栈顶数据
                case "top":
                    int top = minStack.top();
                    result.append(top+",");
                    break;
                default:
            }
        }
        // 去除最后一个逗号,
        String resultStr = result.substring(0, result.length() - 1);
        System.out.println(resultStr+"]");
    }
}                
                










