在O(1)时间复杂度内求栈中最小元素
如何在O(1)时间复杂度内求栈中最小元素呢?可以使用两个栈来实现该问题。
参考《Java程序员面试笔试宝典》的实现方法:使用两个栈结构,一个栈(记为S1)用来存储数据,另一个栈(记为S2)用来指示着栈S1的最小元素。元素入栈S1时,如果当前入栈的元素比栈S2中已有元素还小,则把该元素也入栈S2;出栈时,如果栈S1出栈的元素为当前栈的最小值(等于栈S2栈顶元素),则S2的栈顶元素也出栈,以保证S2栈顶元素始终指示着栈S1的最小值。
一种实现方式如下(Java版):
1 import java.util.Stack; 2 3 /** 4 * 使用两个栈模拟一个栈,该栈可以在O(1)时间内获取栈中最小元素 5 * @author JiaJoa 6 * 7 */ 8 public class GetMinEleFromStack { 9 10 public static void main(String[] args) { 11 Algorithm_MinFromStack ams = new Algorithm_MinFromStack(); 12 MyStack<Integer> ms = ams.new MyStack<Integer>(); 13 14 ms.push(3); 15 ms.push(1); 16 ms.push(2); 17 ms.push(1); 18 19 System.out.println(ms.pop()); 20 System.out.println(ms.pop()); 21 System.out.println(ms.pop()); 22 System.out.println(ms.getMin()); 23 } 24 25 public class MyStack<E>{ 26 Stack<E> s1 = null; 27 Stack<E> s2 = null; 28 29 public MyStack(){ 30 s1 = new Stack<E>(); 31 s2 = new Stack<E>(); 32 } 33 34 //判断是否栈空 35 public boolean isEmpty(){ 36 return s1.isEmpty(); 37 } 38 39 //获取栈中元素个数 40 public int size(){ 41 return s1.size(); 42 } 43 44 //入栈,栈s1保存所有数据,若栈s2为空,则元素直接入栈,否则先和s2中栈顶元素比较,若更小则入栈 45 public void push(E data){ 46 s1.push(data); 47 48 if(s2.isEmpty()) 49 s2.push(data); 50 else{ 51 if((int)data<=(int)s2.peek()) //注意替换该处的元素比较方法 52 s2.push(data); 53 } 54 } 55 56 //出栈,直接弹出s1栈顶元素,同时判断弹出的元素和栈s2栈顶元素的大小,若等于则弹出s2的栈顶元素 57 public E pop(){ 58 E topData = s1.pop(); 59 if(topData.equals(s2.peek())) 60 s2.pop(); 61 return topData; 62 } 63 64 //获取栈顶元素 65 public E peek(){ 66 return s1.peek(); 67 } 68 69 //获取栈中的最小值 70 public E getMin(){ 71 if(s2.isEmpty()) 72 return null; 73 return s2.peek(); 74 } 75 } 76 }