设计一个支持 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.
这道题使用两个栈,或Java 提供的ArrayList 等,还是很好实现的,但是用数组的话就有些小难度了,发现自己还不能很好的操作,所以做一个笔记,记录一下,做题的思路。
维护两个数组,一个用于存数据一个用于存最小值,但要保证每一个数据值存在的时候最小值都是正确的,例如:
data -> 53256 那么最小值数组应为
min -> 53222
因为6 存在的时,data 数组的最小值无疑是2 ,将6 取走后,5 就成了栈顶元素,但此时对应的最小值还是2 ,所以要这样存,
当栈顶是3 时,最小值无疑是3,不再是2 ,所以还要记录之前的最小值,所以采用了数组。
public class MinStack {
private static final int DEFAULT_CAPACITY = 15;
private int[] data;
private int[] min;
private int size;
public MinStack() {
data = new int[DEFAULT_CAPACITY];
min = new int[DEFAULT_CAPACITY];
}
public void push(int x) {
if (size == data.length) {
grow(data.length * 2);
}
if (size == 0 || min[size - 1] > x) {
min[size] = x; // size 不会越界,因为前面做了判断
} else {
min[size] = min[size - 1];
}
data[size] = x; // 先取size 值,然后再++
size++;
}
public void pop() {
if (size == 0) {
return;
}
size--; // -- 到达最后一个
// 如果size 太小了,小于原来的一半,就减小数组容量以节约内存,
// 但不会减小到默认值以内,因为有判断
if (size < data.length / 2) {
grow(data.length / 2);
}
}
public int top() {
if (size == 0) {
throw new RuntimeException();
}
return data[size - 1];
}
public int getMin() {
if (size == 0) {
throw new RuntimeException();
}
return min[size - 1];
}
private void grow(int capacity) {
if (capacity <= DEFAULT_CAPACITY) {
return;
}
data = Arrays.copyOf(data, capacity);
min = Arrays.copyOf(min, capacity);
}
}