设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
可以通过两个栈(stack和min)来实现返回栈中最小元素的功能,其中,min栈的顶部存放stack栈中所有元素的最小值,下面我们用示意图来理解这一过程。
第一步:在stack栈中压入元素4时,stack栈中只有元素4,因此stack栈中最小元素为4,故在min栈中压入元素4。
第二步:在stack栈中再次压入元素2,将此元素与min栈中栈顶元素比较,若小于,则放入,因此min栈中压入元素2。
第三步:在stack栈中再次压入元素3,将此元素与min栈中栈顶元素比较,3>2,因此元素3不放入,放入栈顶元素2至栈中。
第四步:在stack栈中再次压入元素4,将此元素与min栈中栈顶元素比较,4>2,因此元素4不放入,放入栈顶元素2至栈中。
第四步:在stack栈中再次压入元素1,将此元素与min栈中栈顶元素比较,1<2,因此min栈中压入元素1。
至此,min栈中的栈顶即为stack栈中的最小元素,需要取出时,peek即可。
当stack栈需要弹出元素时,min栈也要相应弹出数据。
比如:stack栈弹出元素1,min栈也要相应弹出栈顶元素。
此时min栈中的栈顶还是stack栈中的最小元素2。
下面用java中的内置栈来实现这一过程:
class MinStack {
public Stack<Integer> stack;
public Stack<Integer> min;
public MinStack() {
stack = new Stack<>();
min = new Stack<>();
}
public void push(int val) {
stack.push(val); //stack栈中先压入
if (min.isEmpty() || val < min.peek()) { //若min栈为空,或者压入的值小于min栈的栈顶元素,则min栈压入该值,否则min栈压入min栈的栈顶元素
min.push(val);
} else {
min.push(min.peek());
}
}
public void pop() {
stack.pop();
min.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return min.peek();
}
}
也可以用数组来实现:
class MinStack {
public final int MAXN = 8001;
public int[] stack;
public int[] min;
public int size;
public MinStack() {
stack = new int[MAXN];
min = new int[MAXN];
}
public void push(int val) {
stack[size] = val;
if (size == 0 || val < min[size - 1]) {
min[size] = val;
} else {
min[size] = min[size - 1];
}
size++;
}
public void pop() {
size--;
}
public int top() {
return stack[size - 1];
}
public int getMin() {
return min[size - 1];
}
}