zoukankan      html  css  js  c++  java
  • 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),最小栈的大 小。代码如下

  • 相关阅读:
    P1194 买礼物(建模)
    024 Android 对话框(AlertDialog)的应用(与Android黑马培训班的024相对照学习)
    023 Android 滚动视图(ScollView)
    022 Android 开源项目使用指南
    021 Android 日历视图(Calendarview)
    020 ProgressBar(进度条)、SeekBar(拖动条)与星级评分条(RatingBar)
    019 Android 程序调试技巧汇总
    018 Android 单选按钮(RadioButton)和复选框(CheckBox)的使用
    017 Android ToggleButton(开关函数)与switch (开关按钮)
    016 Android Toast语句应用
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/5222159.html
Copyright © 2011-2022 走看看