在O(1)时间复杂度内求栈中最小元素

时间:2023-02-05 09:55:54

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