leetcode-包含min函数的栈

179 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

  1. MinStack minStack = new MinStack();
  2. minStack.push(-2);
  3. minStack.push(0);
  4. minStack.push(-3);
  5. minStack.min(); --> 返回 -3.
  6. minStack.pop();
  7. minStack.top(); --> 返回 0.
  8. minStack.min(); --> 返回 -2.   提示:
    各函数的调用总次数不超过 20000 次

思路

由于min方法需要O(1)的时间复杂度,所以肯定要用空间去换时间。
栈最重要的性质是后进先出,如果当前压栈1、2、3、4,那么在4弹出之前,1、2、3肯定不会弹出。进一步考虑,栈顶元素确定的情况下,栈中的元素是确定的,那么当前栈中元素的最小值也是确定的。
利用这个性质,我们可以额外定义一个辅助栈minS,当有新元素进入栈时,在minS中也压入一个当前栈的最小值;这样的话,minS的栈顶元素就是当前栈的最小元素。在弹出元素的时候,minS的栈顶元素也要一并弹出。
需要注意的是,这里的最小值需要用Integer.min(x, minS.peek())来获取,而不能全局定义一个min来存储,因为中途有出栈的情况,全局的min就无法维护了。
另外,编码的时候,可以给minS预先压入一个Integer.MAX_VALUE,这样,在压入元素需要从minS获取当前最小值的时候,可以不用考虑minS为空的问题,代码可以简洁一些。

Java版本代码

class MinStack {

    Stack<Integer> s, minS;

    /** initialize your data structure here. */
    public MinStack() {
        s = new Stack<>();
        minS = new Stack<>();
        minS.push(Integer.MAX_VALUE);
    }

    public void push(int x) {
        s.push(x);
        minS.push(Integer.min(x, minS.peek()));
    }

    public void pop() {
        s.pop();
        minS.pop();
    }

    public int top() {
        return s.peek();
    }

    public int min() {
        return minS.peek();
    }
}