在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 }

 

posted @ 2017-11-09 16:49  JiaJoa  阅读(1459)  评论(0编辑  收藏  举报