题目:最小栈
计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) – 将元素 x 推入栈中。
pop() – 删除栈顶的元素。
top() – 获取栈顶元素。
getMin() – 检索栈中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
答案:
我们可能首先会想到在栈里添加一个成员变量存放最小的元素,每次压入一个新元素则更新最小元素,但是如果最小的元素被弹出栈了,就得不到下一个最小的元素了。
所以我们需要把次小元素保存起来。我们可以把每次的最小元素(之前的最小元素和新压入栈的元素两者的较小值)都保存起来放到另一个辅助栈里。
如果每次都把最小元素压入辅助栈,就能保证辅助栈的栈顶一直都是最小元素,但是这样就要求压入和弹出操作 数据栈与辅助栈要同时进行。
import java.util.Stack;
class MinStack {
// 数据栈
private Stack<Integer> data;
// 辅助栈
private Stack<Integer> helper;
/** initialize your data structure here. */
public MinStack() {
data = new Stack<>();
helper = new Stack<>();
}
public void push(int x) {
data.push(x);
if (helper.isEmpty() || helper.peek() >= x) {
helper.push(x);
} else {
helper.push(helper.peek());
}
}
public void pop() {
if (!data.isEmpty()) {
helper.pop();
data.pop();
}
}
public int top() {
if(!data.isEmpty()){
return data.peek();
}
throw new RuntimeException("栈中元素为空,此操作非法");
}
public int getMin() {
if(!helper.isEmpty()){
return helper.peek();
}
throw new RuntimeException("栈中元素为空,此操作非法");
}
}
时间复杂度:O(1)
空间复杂度:O(N)