Min Stack

package cn.edu.xidian.sselab.stack;

import java.util.Stack;


/**
 *
 * @author zhiyong wang
 * title: Min Stack
 * content:
 *  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.
 *      一开始没弄懂这个题的意思,现在搞懂了:最小栈相当于一个辅助栈,用来存储另一一个栈的最小元素的集合:
 *      具体可以这样理解,因为push(x),pop(),top()都可以在O(1)时间内完成,但是getMin()获取最小值的这种操作就不能在O(1)时间内完成
 *      所以这里借助了最小栈的概念
 *      (1)push的时候,stack肯定会存放数据,如果最小栈是空的或者最小栈的栈顶元素小于要存放数据元素,最小栈也会存放数据【这样最小栈一直维护着一个从栈顶到栈底是由小到大排序的】,否则最小栈不存放数据
 *      (2)pop的时候,如果stack是空的则不管,如果不是空的,则弹出栈顶元素,如果最小栈不是空的,并且栈顶元素与stack栈弹出的元素相等,那么最小栈也需要弹出栈顶元素
 *      (3)top的时候,观察stack是否为空,如果为空则不管,如果不为空,则查看栈顶元素,与最小栈没有关系
 *      (4)getMin的时候,这个时候跟stack是没有关系的,如果最小栈不为空,在查看栈顶元素
 *  
 *
 */
public class MinStack {
    
    Stack<Integer> stack = new Stack<Integer>();
    Stack<Integer> minStack = new Stack<Integer>();
    
    public void push(int x){
        stack.push(x);
        if(minStack.isEmpty() || minStack.peek() >= x)
            minStack.push(x);        
    }
    
    public void pop(){
        if(stack.isEmpty())
            return ;
        int temp = stack.pop();
        if(!minStack.isEmpty() && temp == minStack.peek())
            minStack.pop();
    }
    
    public int top(){        
        return stack.peek();
    }
    
    public int getMin(){
        return minStack.peek();        
    }
}

这个地方参考了讲解:http://www.tuicool.com/articles/zARfAj

这道题是关于栈的题目,实现一个栈的基本功能,外加一个获得最小元素的操作。正常情况下top,pop和push操作都是常量时间的,而主要问题就在于这 个getMin上面,如果遍历一遍去找最小值,那么getMin操作就是O(n)的,既然出出来了这道题就肯定不是这么简单的哈。比较容易想到就是要追溯 这个最小值,在push的时候维护最小值,但是如果pop出最小值的时候该如何处理呢,如何获得第二小的值呢?如果要去寻找又不是常量时间了。解决的方案 是再维护一个栈,我们称为最小栈,如果遇到更小的值则插入最小栈,否则就不需要插入最小栈(注意这里正常栈是怎么都要插进去的)。这里的正确性在于,如果 后来得到的值是大于当前最小栈顶的值的,那么接下来pop都会先出去,而最小栈顶的值会一直在,而当pop到最小栈顶的值时,一起出去后接下来第二小的就 在pop之后最小栈的顶端了。如此push时最多插入两个栈一个元素,是O(1),top是取正常栈顶,自然是O(1),而pop时也是最多抛出两个栈的 栈顶元素,O(1)。最后getMin只需要peek最小栈顶栈顶即可,所以仍是O(1),实现了所有操作的常量操作,空间复杂度是O(n),最小栈的大 小。代码如下

原文地址:https://www.cnblogs.com/wzyxidian/p/5222159.html