常见面试题之栈的最小值
栈的最小值
https://leetcode-cn.com/problems/min-stack-lcci/
面试题 03.02. 栈的最小值
请设计一个栈,除了常规栈支持的pop与push函数以外,还支持min函数,该函数返回栈元素中的最小值。执行push、pop和min操作的时间复杂度必须为O(1)。示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
分析:
【方式一】
尝试用额外的栈 来记录数据栈的最小值
dataStack -2 0 -3 1
minStack -2 -2 -3 -3
dataStack -2 0 -4
minStack -2 -2 -4
public class MinStack {
// 数据栈
Stack<Integer> dataStack = new Stack<>();
// 存储最小值的额外栈
Stack<Integer> minStack = new Stack<>();
/**
* initialize your data structure here.
*/
public MinStack() {
}
public void push(int x) {
dataStack.push(x);
// 比较新元素 和minStack中栈顶元素(之前所有元素的最小值) 谁更小
if (!minStack.isEmpty() && minStack.peek() < x) {
// 如果栈顶元素更小 再存进栈一次
minStack.push(minStack.peek());
} else {
minStack.push(x);
}
}
public void pop() {
dataStack.pop();
minStack.pop();
}
public int top() {
return dataStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
【方式二】
不使用额外的栈 使用变量来标记栈的最小元素
核心问题在于 如何记录之前的最小值?
[-2 0 -3 1 ]
dataStack [-2 0 -2 -3 1]
min -2 -> -3
dataStack [-2 0]
min -2
public class MinStack1 {
Stack<Integer> dataStack = new Stack<>();
int min = Integer.MAX_VALUE;
public void push(int x) {
// 如果新元素使最小值发生变化 则会存储两个值 (原来的最小值 当前的最小值)
if (min >= x) {
// 如果栈为空 说明是第一个元素 此时一定min>x
if (!dataStack.isEmpty()) {
dataStack.push(min);
}
// 最小值重新赋值
min = x;
}
dataStack.push(x);
}
public void pop() {
if (dataStack.isEmpty()) return;
if (dataStack.size() == 1) {
min = Integer.MAX_VALUE;
} else if (min == dataStack.peek()) {
dataStack.pop();
min = dataStack.peek();
}
// 如果移除的不是最小值 直接pop
// 如果移除的是最小值 前面移除一次 再移除之前保存的最小值
dataStack.pop();
}
public int top() {
return dataStack.peek();
}
public int getMin() {
return min;
}
}