LeetCode(155)-Min Stack(最小栈-三种解法)

题目:

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.

翻译:

设计一个栈,支持push、pop、top和在常量时间内检索最小元素。
push(x)——将元素x推入堆栈。
pop()——删除堆栈顶部的元素。
top()——获取top元素。
getMin()——检索堆栈中的最小元素。
例子:
MinStack = new MinStack();
minStack.push (2);
minStack.push (0);
minStack.push (3);
minStack.getMin ();- - >返回3。
minStack.pop ();
minStack.top ();- - >返回0。
minStack.getMin ();- - >返回2。

方法一:

我们采用 两个栈的数据结构 来完成,stk作为正常使用的主栈,s作为存储当前最小值的栈。
对于最小值的入栈问题,只有当栈为空或者栈顶元素大于等于要push的元素时,才进行入栈操作。
在pop时,如果主栈的元素等于当前栈顶的元素,那么最小栈也需要出栈。因为最小值的元素不在栈内了,所以需要最小栈也出栈。这里我们需要解释上面最小栈入栈时为什么相等的元素也要入栈,假如相等元素不入栈,当pop最小元素时,最小栈元素也要出栈,但是此时主栈中依然存在于出栈元素相等的元素,这时当前最小值。而最小栈此元素已经出栈,所以需要将同等大小的最小元素入栈。

代码实现:

class MinStack {
    Stack<Integer> s;
    Stack<Integer> stk;

    /** initialize your data structure here. */
    public MinStack() {
        s=new Stack();
        stk=new Stack();
    }
    
    public void push(int x) {
        stk.push(x);
        if(s.empty()||x<=s.peek())
            s.push(x);
    }
    
    public void pop() {
        if(stk.pop().equals(s.peek()))
            s.pop();
    }
    
    public int top() {
        return stk.peek();
    }
    
    public int getMin() {
        return s.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();
 */

方法二:

我们采用在栈中存储两个元素的的数据结构,一个是当前元素值,一个是第二小的值。
每当我们入栈时,我们总是将当前最小值作为第二小的值来存储(实际上可能并不是), 这样做的目的是,假如当前值为最小值,当它出栈时,我们可以快速找到第二小的值。因此这个第二小的值只有在当前元素时最小元素时才有用。

代码实现:

class MinStack {
     int valMin;
     Stack<SecondMin> s;
     class SecondMin{
         int num;
         int secondMin;
         public SecondMin(int num,int secondMin){
             this.num=num;
             this.secondMin=secondMin;
         }
    }
    
    /** initialize your data structure here. */
    public MinStack() {
        this.s=new Stack();
        this.valMin=Integer.MAX_VALUE;
    }
    
    public void push(int x) {
        s.push(new SecondMin(x,valMin));
        valMin=x<valMin?x:valMin;
    }
    
    public void pop() {
        SecondMin se=s.pop();
        if(se.num==valMin)
            valMin=se.secondMin;
    }
    
    public int top() {
        return s.peek().num;
    }
    
    public int getMin() {
        return valMin;
    }
}

/**
 * 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();
 */

方法三:

上面两种方法都有多余开辟内存的问题,实际上,我们可以对方法一进行改进,对于当前最小元素,实际上不需要去开辟新的栈。我们用一个变量来存储当前最小元素,当新push的元素小于当前最小元素时,我们将已经成为第二小的元素压入栈,在将要push的元素压入栈。此时相当于压入两次元素。因此在我们pop的时候,只要pop的元素等于当前最小的元素,那么他后面肯定跟着一个第二小的元素,那么我们也将它pop出来做最小元素。

代码实现:

class MinStack {
     int valMin;
     Stack<SecondMin> s;
     class SecondMin{
         int num;
         int secondMin;
         public SecondMin(int num,int secondMin){
             this.num=num;
             this.secondMin=secondMin;
         }
    }
    
    /** initialize your data structure here. */
    public MinStack() {
        this.s=new Stack();
        this.valMin=Integer.MAX_VALUE;
    }
    
    public void push(int x) {
        s.push(new SecondMin(x,valMin));
        valMin=x<valMin?x:valMin;
    }
    
    public void pop() {
        SecondMin se=s.pop();
        if(se.num==valMin)
            valMin=se.secondMin;
    }
    
    public int top() {
        return s.peek().num;
    }
    
    public int getMin() {
        return valMin;
    }
}

/**
 * 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();
 */

你可能感兴趣的:(LeetCode(155)-Min Stack(最小栈-三种解法))