1. 要求 及思路
实现一个最小栈,主要实现包括以下方法,且满足操作的时间复杂度为O(1):
void push(E val): 压入一个元素;
E pop():从栈中弹出一个元素;
E top():返回栈顶元素;
E min():返回栈中最小元素;
思路:这里考虑用2个栈实现,用内存换取效率。
其中一个栈用来存当前容器中的最小值;另一个栈用来存所有元素。
2. Java实现
Q: 注意,这里的Stack用ArrayDeque而不是Stack的原因是什么?
A: 点击这里可以查看详细的Q&A。
The javadoc of ArrayDeque says ” This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue.”
The point is that if you want queue behavior, you could use LinkedList, but ArrayDequeue will(often) be faster. If you want stack behavior, you could use Stack, but ArrayDeque will(often) be faster.ArrayDeque: 的实现可以保证其具有LIFO的集合特性–即栈的特性;且有FIFO的特性。故而,在我们要使用栈的特性的时候我们可以考虑使用ArrayDeque而不是Stack, 因为其具有性能上的优势;在我们要使用队列的一些特性时我们考虑使用ArrayDequeue而不是LinkedList, 同样因为其具有性能的优势。
package com.fqyuan.minstack;
import java.util.ArrayDeque;
import java.util.Random;
public class MinStack {
public static void main(String[] args) {
MinStack minStack = new MinStack();
Random random = new Random();
for (int i = 0; i < 10; i++) {
int val = random.nextInt(100);
System.out.print(val + " ");
minStack.push(val);
}
System.out.println();
// int val = minStack.pop();
int minVal = minStack.min();
System.out.println(minVal);
int val = minStack.pop();
System.out.println(val);
minVal = minStack.min();
System.out.println(minVal);
}
private ArrayDeque<Integer> stack = new ArrayDeque<>();
private ArrayDeque<Integer> minStack = new ArrayDeque<>();
public void push(int val) {
if (minStack.isEmpty() || val < minStack.peek())
minStack.push(val); // Insert an element at the front of the deque.
stack.push(val);
}
public int pop() {
if (minStack.peek() == stack.peek())
minStack.poll(); // Retrieve and remove the head of the stack.
return stack.poll();
}
public int top() {
return stack.peek(); // Retrieve, but not remove the head of the deque,
// or null if the deque is null.
}
public int min() {
return minStack.peek();
}
}