题目:
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) -- 将元素 x 推入栈中。
- pop() -- 删除栈顶的元素。
- top() -- 获取栈顶元素。
- getMin() -- 检索栈中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路:
这道题的解法很简单——重新设计一个类,类中定义两个stack,一个就是普通的栈,另外一个是最小元素的栈,只有push的元素小于等于栈顶元素才入栈。
这个解法完全正确,但是思路真的有这么简单吗?我们来思考一下——为什么我们存储最小元素的数据结构要是栈。
- 首先我们不能用一个普通的整型来存储,不然的话,如果pop掉普通栈中的该元素,我们就失去最小值了。
- 用栈其实是最符合我们的思维的,因为我们存储元素用的是普通的栈,所以最好也用栈来追踪最小值。
- 最后,想一想当我们把最小元素的栈元素,在普通栈中pop了后的结果——最小元素栈中存放的就是下面所有数据中最小的,所以完全没有问题。
AC代码:
#include<iostream>
#include<stack>
using namespace std;
class MinStack {
private:
stack<int> normal_;
stack<int> min_;
public:
MinStack() = default;
void push(int x) {
normal_.push(x);
if (min_.empty() || x <= min_.top()) {
min_.push(x);
}
}
void pop() {
if (normal_.top() == min_.top()) {
min_.pop();
}
normal_.pop();
}
int top() { return normal_.top(); }
int getMin() { return min_.top(); }
};
int main() {
MinStack s;
s.push(-2);
s.push(0);
s.push(-3);
cout << s.getMin() << endl;
s.pop();
cout << s.top() << endl;
cout << s.getMin() << endl;
return 0;
}
其他经验:
注意第一次压栈的时候,我们不能使用top方法访问栈顶元素。