持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 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 次
思路
由于min方法需要O(1)的时间复杂度,所以肯定要用空间去换时间。
栈最重要的性质是后进先出,如果当前压栈1、2、3、4,那么在4弹出之前,1、2、3肯定不会弹出。进一步考虑,栈顶元素确定的情况下,栈中的元素是确定的,那么当前栈中元素的最小值也是确定的。
利用这个性质,我们可以额外定义一个辅助栈minS,当有新元素进入栈时,在minS中也压入一个当前栈的最小值;这样的话,minS的栈顶元素就是当前栈的最小元素。在弹出元素的时候,minS的栈顶元素也要一并弹出。
需要注意的是,这里的最小值需要用Integer.min(x, minS.peek())来获取,而不能全局定义一个min来存储,因为中途有出栈的情况,全局的min就无法维护了。
另外,编码的时候,可以给minS预先压入一个Integer.MAX_VALUE,这样,在压入元素需要从minS获取当前最小值的时候,可以不用考虑minS为空的问题,代码可以简洁一些。
Java版本代码
class MinStack {
Stack<Integer> s, minS;
/** initialize your data structure here. */
public MinStack() {
s = new Stack<>();
minS = new Stack<>();
minS.push(Integer.MAX_VALUE);
}
public void push(int x) {
s.push(x);
minS.push(Integer.min(x, minS.peek()));
}
public void pop() {
s.pop();
minS.pop();
}
public int top() {
return s.peek();
}
public int min() {
return minS.peek();
}
}