面试题三:设计包括 min 函数的栈。
3.设计包括 min 函数的栈。
定义栈的数据结构,要求加入一个 min 函数。可以得到栈的最小元素。
要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。
思路分析:
a.要想一个在栈中找出栈的最小值,且时间复杂度为1,我们可能回忆到每次向栈插入push()一个值都对其进行排序操作,将最小值放在栈顶,可是我们非常快会发现这样的方式破坏了栈的结构,不再满足栈的先进先出的特点了(FIFO),此法不行
b.通过一个成员函数来保存最新值,但当最小元素弹出栈pop()时,我们无法得到次小元素,所以此法也不行。
c.大家可能立刻想到用数组了。通过数组来保存对栈进行插入或删除后栈中的最小值,但这有一个弊端,我们不知道要给数组申请大多的地址空间,由于我们事先无法确定会插入多少个数到栈中,此法不优
d.我们能够使用一个辅助栈来存放最小值
操作:
option | dataStack栈 | minStack栈 |
---|---|---|
push(3) | 3 | 3 |
push(5) | 3,5 | 3,3 |
push(2) | 3,5,2 | 3,3,2 |
push(6) | 3,5,2,6 | 3,3,2,2 |
pop() | 3,5,2 | 3,3,2 |
pop() | 3,5 | 3,3 |
如今我知道要得到栈中的最小值,就是辅助栈的栈顶元素故调用minStack.peek()。
Java代码例如以下:
package com.WuKung.blog; import java.util.Stack; /** * @author WuKung * @csdnURL http://blog.csdn.net/wu_kung/ * @createdDate 2014-4-7 下午11:18:47 */ public class StackWithMin<E extends Comparable<E>> extends Stack<E>{ Stack<E> data; Stack<E> min; public StackWithMin(Stack<E> data,Stack<E> min){ this.data = data; this.min = min; } @Override public E push(E item) { // TODO Auto-generated method stub if(data.size()==0||item.compareTo(min.peek())<0){ min.push(item); }else{ min.push(min.peek()); } data.push(item); return super.push(item); } @Override public synchronized E pop() { // TODO Auto-generated method stub if(!min.isEmpty()&&!data.isEmpty()){ min.pop(); data.pop(); } return super.pop(); } public E min(){ return min.peek(); } }測试类:
package com.WuKung.blog; import java.util.Stack; /** * @author WuKung * @csdnURL http://blog.csdn.net/wu_kung/ * @createdDate 2014-4-8 上午12:17:18 */ public class StackT { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Stack<Integer> data = new Stack<Integer>(); Stack<Integer> min = new Stack<Integer>(); StackWithMin<Integer> test = new StackWithMin<Integer>(data, min); test.push(new Integer(3)); test.push(new Integer(5)); test.push(new Integer(2)); test.push(new Integer(6)); test.pop(); test.pop(); System.out.println(test.min()); } }
測试结果: