一、题目
题目链接:力扣
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的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 次
二、题解
1、思路
最初想法:我最初的想法是使用一个变量记录当前的最小值,但是当再次压栈一个和最小值相等的值时,就会存在两个最小值,当然可以使用另一个变量记录这个最小值出现的次数,每次弹栈一个最小值减去1;但是当这个最小值全部被弹栈时,如何寻找下一个最小值呢?显然是无法找到的,也就是说只用一个变量记录当前的最小值是不够的。
解题思路:
首先看这里的动图:力扣。
按照上面的思路,我们只需要设计一个数据结构,使得每个元素 a 与其相应的最小值m时刻保持一一对应。因此我们可以使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。
当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中;当一个元素要出栈时,我们把辅助栈的栈顶元素也一并弹出;
在任意一个时刻,栈内元素的最小值就存储在辅助栈的栈顶元素中。
2、代码实现
如何求得当前的最小值,并将其存放到栈中呢?我们只需要求出第一次压栈时的最小值,其余的将压栈元素与存储最小元素的辅助栈栈顶元素(上次压栈后的最小值)。
class MinStack {
private:
stack<int> x_stack;
stack<int> min_stack;
public:
/** initialize your data structure here. */
MinStack() {
min_stack.push(INT_MAX);// 保证第一个元素作为最小值压栈到最小值栈
}
void push(int x) {
x_stack.push(x);
// 其中::min表示全局的min函数
min_stack.push( ::min(x, min_stack.top()) );// 将要压栈值和最小栈栈顶元素比较得到最小元素
}
void pop() {
x_stack.pop();
min_stack.pop();// 同时弹栈
}
int top() {
return x_stack.top();
}
int min() {
return min_stack.top();
}
};
3、复杂度分析
时间复杂度:O(1);
空间复杂度:O(n)。