剑指Offer_#30_包含min函数的栈
剑指Offer_#30_包含min函数的栈
Contents
题目
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
提示:
各函数的调用总次数不超过 20000 次
思路分析
看到题目,最简单的想法可能是:维护一个int
类型的变量,存储当前栈中的最小值。
这个思路是有问题的,因为如果你将这个最小值弹出了,那么再次调用min()
函数就没有可返回的了。
所以考虑在类中增加一个辅助的栈类型的成员变量,不仅仅存储最小值,还存储次最小值,第三最小值等等...
所以有两个栈,
data
栈:要操作的栈本身min
栈:辅助栈,和data
栈同步进行修改
各个函数的设计
题中要求我们实现4个函数:push()
,pop()
,top()
,min()
,关键在于push
和pop
的设计。
push(x)
函数
1. 将x
压入data
栈
2. 栈为空 或x
<min.peek()
,将x压入min
栈;否则,将min
栈的栈顶元素再次压入min
栈。(min
栈的栈顶表示的就是data
栈在目前情况下的最小值。)pop()
函数
弹出的时候两个栈保持同步。- 弹出
data
栈顶元素 - 弹出
min
栈顶元素
- 弹出
top
函数
返回data
的栈顶元素即可 。min
函数
返回min
的栈顶元素即可。
解答
class MinStack {
Stack<Integer> data,min;
/** initialize your data structure here. */
public MinStack() {
data = new Stack<>();
min = new Stack<>();
}
public void push(int x) {
data.add(x);
if(min.empty() || x < min.peek()) min.add(x);
else min.add(min.peek());
}
public void pop() {
if(!min.empty() && !data.empty()){
min.pop();
data.pop();
}
}
public int top() {
return data.peek();
}
public int min() {
return min.peek();
}
}