问题
实现一个栈,该栈带有出栈(pop)、入栈(push)、取最小元素(getMin)3个方法。要保证这3个方法的时间复杂度都是O(1)。
解释
为了实现一个栈,同时满足 pop
、push
和 getMin
操作的时间复杂度均为 O(1),我们需要在栈中存储元素的同时,额外维护一个最小值的信息。一个常见的方法是使用两个栈,一个用于存储实际元素(我们称之为 dataStack
),另一个用于存储对应位置的最小值(我们称之为 minStack
)。当 dataStack
进行 push
或 pop
操作时,minStack
也会进行相应的操作以保持同步,从而确保 getMin
操作的时间复杂度为 O(1)。
代码
java
import java.util.Stack;
public class MinStack {
// 用于存储实际数据的栈
private Stack<Integer> dataStack;
// 用于存储对应位置最小值的栈
private Stack<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
dataStack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
dataStack.push(x);
// 如果minStack为空,或者x小于等于minStack的栈顶元素,则将x也压入minStack
if (minStack.isEmpty() || x <= minStack.peek()) {
minStack.push(x);
}
}
public void pop() {
// 如果dataStack弹出的元素等于minStack的栈顶元素,则minStack也需要弹出
if (!dataStack.isEmpty() && dataStack.peek().equals(minStack.peek())) {
minStack.pop();
}
dataStack.pop();
}
public int top() {
// 栈不为空时,返回栈顶元素
if (!dataStack.isEmpty()) {
return dataStack.peek();
}
throw new RuntimeException("Stack is empty");
}
public int getMin() {
// 栈不为空时,返回最小值栈的栈顶元素
if (!minStack.isEmpty()) {
return minStack.peek();
}
throw new RuntimeException("Stack is empty");
}
}
// 示例用法
public class Main {
public static void main(String[] args) {
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
System.out.println(minStack.getMin()); // 返回 -3
minStack.pop();
System.out.println(minStack.top()); // 返回 0
System.out.println(minStack.getMin()); // 返回 -2
}
}
这段代码定义了一个 MinStack
类,它使用两个栈来分别维护数据和对应位置的最小值。push
操作会同时向两个栈中添加元素,而 pop
操作会检查两个栈的栈顶元素是否相同(即被移除的元素是否是当前最小值),如果是,则同时从两个栈中移除。通过这种方式,我们可以确保 getMin
操作的时间复杂度为 O(1)。