题目:自己实现一个栈,在o(1)时间内获得最小值,o(1)时间内push,pop。
第一次看到这个题时,我的第一反应是
没反应....
第二反应是..... 获得最小值不应该遍历吗?怎么o(1)时间内完成。
看了答案后,哦.....原来用辅助栈就能解决。
后来再看到这道题时。
嘿嘿,这道题我会
02 解题
首先回顾一下,栈结构:入口和出口都在一端
栈结构本身提醒push入栈和pop出栈的时间复杂度就是o(1)
那么如何在O(1)时间内获得最小值呢。小伙伴们应该会求无序数组的最小值,找第一个数作为参照,顺序对比数组中所有的值,比存储的数值小则替换,否则就下一个数。如下图
2比3小替换,
1比2小,替换2为1
-1比1小,替换1为-1
-8比 -1 小替换为 -8
遍历最后一个数值,6比-8大,仍然为-8
遍历到每个数值时,所存储的最小值,就是那个数之前所有的数的最小值。如
-1,就是3,2,1,-1里面的最小值。
把上述替换过程改为入栈过程,两个栈,蓝色为正常的dataStack,红色为辅助栈minStack
dataStack.push(2) . 新数值2比3小入栈,入栈2到辅助栈中minStack.push(2)
dataStack.push(1) 新数值1,1比2小,入栈1到辅助栈中
类似的入栈-1,-8 ,
dataStack.push(6) 入栈数值6,辅助栈顶元素-8比6比小,所以辅助栈,入栈栈顶元素-8
获取当前栈的最小值,即从minStack.peek()可得,
03 代码&总结
minStack入栈 要么是当前的栈顶元素,要么是更小的入栈元素。
dataStack正常入栈
代码
import java.util.Stack;
public class 面试题21含min函数的栈 {
private Stack<Integer> minStack = new Stack<>();
private Stack<Integer> dataStack = new Stack<>();
public Integer min() {
if (minStack.size() <= 0 && dataStack.size() <= 0) {
throw new RuntimeException("栈中没有元素");
}
return minStack.peek();
}
public void push(Integer value) {
dataStack.push(value);
if (minStack.size() == 0 || value < minStack.peek()) {
minStack.push(value);
} else {
minStack.push(minStack.peek());
}
}
public Integer pop() {
if (minStack.size() <= 0 && dataStack.size() <= 0) {
throw new RuntimeException("栈中没有元素");
}
minStack.pop();
return dataStack.pop();
}
public boolean isEmpty() {
return dataStack.isEmpty();
}
public static void main(String[] args) {
面试题21含min函数的栈 栈 = new 面试题21含min函数的栈();
for (int i = 0; i <= 10; i ++)
栈.push(i + 1);
栈.pop();
System.out.println(栈.min());
面试题21含min函数的栈 栈2 = new 面试题21含min函数的栈();
for (int i = 10; i > 0; i --)
栈2.push(i);
栈2.pop();
System.out.println(栈2.min());
面试题21含min函数的栈 栈3 = new 面试题21含min函数的栈();
栈3.push(1);
栈3.push(2);
栈3.push(-1);
栈3.push(8);
栈3.push(7);
栈3.push(6);
栈3.push(9);
while (!栈3.isEmpty()) {
System.out.println(栈3.min());
栈3.pop();
}
}