解题思路:
- 和一般栈的区别是需要记录栈存放的最小值,当栈元素更新的时候需要更新这个最小值
- 一开始想到的是使用一个链表进行记录,但是这样的话需要将栈元素中存放的元素变为节点地址,然后维护节点的顺序(本质上可以实现,但是过于低效)
- 2方法不可行的时候,需要注意到栈本身的特性,最后入栈的元素会先出栈,也就是说,如果当前入栈的元素如果不是最小的值,那么代表最小的值是先于该元素入栈的,这样该元素出栈入栈其实是不会更新最小值的。
- 基于第三点的认知,因为入栈的元素可能存在多个相等值,比如入栈了2/0/0/0/-1,当-1 pop 0 pop 0 pop时,最小值还是0,也就是说最小值有几个,我们就需要保存几个。
- 基于上述思想归纳,可以使用一个辅助记录最小元素的栈。
- 入栈,当入栈元素<=当前最小元素的时候,在正常栈和最小栈同时入栈;当入栈元素>当前最小元素的时候,只入栈正常栈。
- 出栈,当出栈元素==当前最小元素时,正常栈和最小栈同时出栈;当出栈元素>当前最小元素时,仅正常栈出栈。
class MinStack {
// 存元素栈
int[] stack;
int top = -1;
//
int[] minStack;
int minIndex = -1;
/** initialize your data structure here. */
public MinStack() {
stack = new int[20000];
minStack = new int[20000];
}
public void push(int x) {
// 注意数组初始化的值为0,用length获取的是初始化数组的长度,实际使用元素的长度需要使用标识记录
if (minIndex == -1) {
minStack[++minIndex] = x;
} else {
if(x <= minStack[minIndex]) {
minStack[++minIndex] = x;
}
}
stack[++top]= x;
}
public void pop() {
int x = stack[top--];
if (x == minStack[minIndex]) {
minIndex --;
}
}
public int top() {
return stack[top];
}
public int min() {
return minStack[minIndex];
}
}
Q.E.D.