背景
设计一个支持 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.
分析
分两种,一种自己实现栈,另一种是用现成的Stack类,更关注于如何实现常数getMin 方法。
public static class MinStack {
private int min;
/** 第一次push改变状态,pop完所有元素改变状态 */
private boolean minInited = false;
private int[] table;
private int p = -1;
public MinStack() {
table = new int[10];
}
public void push(int x) {
ensureCapacity();
p++;
table[p] = x;
if (!minInited) {
min = x;
minInited = true;
} else {
if (x < min) {
min = x;
}
}
}
public void pop() {
//弹出去的正好是最小值,此时需要重新找最小值
if (p > 0 && table[p] == min) {
min = table[0];
for (int i = 0; i <= p - 1; i++) {
if (table[i] < min) {
min = table[i];
}
}
}
p--;
if (p < 0) {
p = -1;
min = 0;
minInited = false;
//至此,最小值需要重新初始化
}
}
public int top() {
return p < 0 ? 0 : table[p];
}
private void ensureCapacity() {
if (p >= table.length - 1) {
int[] newTable = new int[table.length * 2];
System.arraycopy(table, 0, newTable, 0, table.length);
this.table = newTable;
}
}
/**
* 常数时间
*
* @return
*/
public int getMin() {
return min;
}
}
第二种,使用现成的类
public static class MinStack {
private Stack<Integer> stack = new Stack<>();
private Stack<Integer> helper = new Stack<>();
public MinStack() {
}
public void push(int x) {
stack.push(x);
helper.push(helper.size()==0?x:Math.min(x,helper.peek()));
}
public void pop() {
stack.pop();
helper.pop();
}
public int top() {
return stack.peek();
}
/**
* 常数时间
*
* @return
*/
public int getMin() {
return helper.peek();
}
}
以上两种思路占用时间及内存相近,并没有达到太好的跑分。