最小栈的实现

问题描述:

实现一个栈,带有出栈(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

posted @ 2017-10-19 22:44  Qcer  阅读(266)  评论(0编辑  收藏  举报