正常状况下top。pop和push操做都是常量时间的,而主要问题就在于这个getMin上面,假设遍历一遍去找最小值,那么getMin操做就是O(n)的,既然出出来了这道题就确定不是这么简单的哈。比較easy想到就是要追溯这个最小值。在push的时候维护最小值,但是假设pop出最小值的时候该怎样处理呢,怎样得到第二小的值呢?假设要去寻找又不是常量时间了。java
解决的方案是再维护一个栈,咱们称为最小栈,假设遇到更小的值则插入最小栈。不然就不需要插入最小栈(注意这里正常栈是怎么都要插进去的)。面试
这里的正确性在于。假设后来获得的值是大于当前最小栈顶的值的,那么接下来pop都会先出去,而最小栈顶的值会一直在,而当pop到最小栈顶的值时,一块儿出去后接下来第二小的就在pop以后最小栈的顶端了。如此push时最多插入两个栈一个元素,是O(1)。top是取正常栈顶,天然是O(1)。而pop时也是最多抛出两个栈的栈顶元素,O(1)。最后getMin仅仅需要peek最小栈顶栈顶就能够。因此还是O(1)。实现了所有操做的常量操做。空间复杂度是O(n),最小栈的大小。代码例如如下:post
class MinStack { ArrayList<Integer> stack = new ArrayList<Integer>(); ArrayList<Integer> minStack = new ArrayList<Integer>(); public void push(int x) { stack.add(x); if(minStack.isEmpty() || minStack.get(minStack.size()-1)>=x) { minStack.add(x); } } public void pop() { if(stack.isEmpty()) { return; } int elem = stack.remove(stack.size()-1); if(!minStack.isEmpty() && elem == minStack.get(minStack.size()-1)) { minStack.remove(minStack.size()-1); } } public int top() { if(!stack.isEmpty()) return stack.get(stack.size()-1); return 0; } public int getMin() { if(!minStack.isEmpty()) return minStack.get(minStack.size()-1); return 0; } }