zoukankan      html  css  js  c++  java
  • 最小栈的实现

    问题描述:

    实现一个栈,带有出栈(pop),入栈(push),取最小元素(getMin)三个方法。要保证这三个方法的时间复杂度都是O(1)。

    问题分析:

    假设存储元素的栈为ms栈;

    主要的难点在于获取栈最小元素getMin()要保证其时间复杂度为O(1);

    而且由于存在push()和pop()操作,栈中最小元素currMin随时可能会因为入栈元和弹出操作而发生动态变化,因此需要一种机制,能够时刻记录当前栈的最小元素;

    这里,可以考虑用一个辅助栈aux,当ms栈的第一个元素入栈时,aux将第一个元素的索引0入栈;

    那么后续如何来保证aux的栈顶元素实时记录着ms栈的最小元素的索引呢?

    当入栈操作时,如果入栈元素小于当前栈中最小元素(aux栈顶元素所对应的元素),更新当前最小元素,并将新的最小元素的索引(也即是top值)入辅助栈;

    当出栈操作时,如果出栈元素等于当前栈中最小元素,先将aux栈顶元素弹出,在更新当前最小元素;

    如此操作可保证aux的栈顶元素实时记录着ms栈当前元素的最小值。

    实现:

    package agother;
    import java.util.ArrayList;
    import java.util.Stack;
    public class MinStack {
    
        private ArrayList<Integer> ms = new ArrayList<Integer>();//栈元素的存储借助ArrayList
        private Stack<Integer> aux = new Stack<Integer>();//辅助的普通栈
        private int currMin = Integer.MAX_VALUE;//当前最小值
        private int top = -1;//栈顶指针
        public void push(int ele){
            ms.add(ele);
            top++;
            if (ele < currMin) {//如果入栈元素小于当前栈中最小与元素,更新当前最小元素,并将新的最小元素的位置(也即是top值)入辅助栈
                currMin = ele;
                aux.push(top);
            }
        }
        public Integer pop(){
            if (top<0) {return null;}
            Integer ele = ms.remove(top);
            top--;
            if (ele == currMin) {//如果出栈元素等于当前栈中最小元素,更新当前最小元素为次小元素,并弹出aux栈顶元素。
                aux.pop();
                currMin = ms.get(aux.peek());
            }
            return ele;
        }
        /*
         * 实际上,辅助栈的栈顶元素始终记录的是ms栈中最小元素的索引值
         * 即是是在ms压栈或者出栈的过程中,通过调整,任然保持着这一事实
         * 因此getMin()方法总能以O(1)的时间复杂度正确找到ms栈的最小元素
         * */
        public Integer getMin(){
            if (aux.isEmpty()) {
                return null;
            }else {
                return currMin;//或者返回ms.get(aux.peek())
            }
        }
        public int size(){
            return top+1;
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            try {
                MinStack ms = new MinStack();
                ms.push(10);
                ms.push(3);
                ms.push(5);
                ms.push(15);
                ms.push(2);
                ms.push(8);
    //            System.out.println(ms.size());
    //            System.out.println(ms.getMin());
    //            System.out.println(ms.pop());
    //            System.out.println(ms.pop());
    //            System.out.println(ms.pop());
    //            System.out.println(ms.pop());
    //            System.out.println(ms.pop());
                System.out.println(ms.getMin());
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    
    }

    转载请注明原文地址:http://www.cnblogs.com/qcblog/p/7695988.html

  • 相关阅读:
    (转)AS3中实现卡马克卷轴算法
    (转)flash位图缓存cacheAsBitmap
    (转)addFrameScript函数的纠结
    (转)flash安全策略文件
    (转)脏矩形技术学习
    (转)stopImmediatePropagation 和stopPropagation的区别
    (转)flash对象池技术
    揭开嵌入式C面试题背后的玄机
    一次遍历找链表倒数第n个节点
    N!的尾部连续0的个数
  • 原文地址:https://www.cnblogs.com/qcblog/p/7695988.html
Copyright © 2011-2022 走看看