这题是容易题,但我觉得很值得好好研究。
我开始是想用一个链表来maintain最小值,发现太慢,不能再常数时间内返回,后来又想用一个数组,但是很难插入最小值。参考了答案才恍然大悟。
解法1:用两个栈,其中一个保存当前的最小值。思路比较好懂。
举例如下: 输入数据为arr={10,6,8,7,5,12},则minarr={10,6,6,6,5,5}。当pop()时,minarr跟arr同步pop()即可,一次只需pop一个。
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
minarr.push_back(INT_MAX);
}
void push(int x) {
arr.push_back(x);
if (x<minarr.back())
minarr.push_back(x);
else
minarr.push_back(minarr.back());
}
void pop() {
arr.pop_back();
minarr.pop_back();
}
int top() {
return arr.back();
}
int getMin() {
return minarr.back();
}
private:
vector<int> arr;
vector<int> minarr;
};
解法2则更为巧妙,只用一个array,但是加了些冗余的元素。
举例如下: 输入数据为{10,6,8,7,5,12},则arr={10, 10, 6, 8, 7, 6, 5, 12}。冗余元素发生在push过程中,当前元素比minv小的时候,我们把旧的minv和当前元素先后push_back到arr里面,并更新minv。当pop()时,如果我们发现arr.back()是minv,则先pop(),然后我们知道下一个就是接下来的minv,我们把minv更新后再把它pop()掉就可以了。
注意:
1) push()中必须用<=,如果我们用<的话,当输入数据为{10,6,8,7,5,5},则arr={10, 10, 6, 8, 7, 6, 5, 5}。那么当pop()的时候,两个5都pop()掉,并且当前的minv又是5,则出错。用了<=后,arr={10, 10, 6, 8, 7, 6, 5, 5, 5},则第一个5 pop()掉后会顺便pop()掉第2个5,此时minv=5,第3个5 pop()的时候会把minv更新为6, 并且顺便把6也pop()掉。
2) 注意vector的pop_back()和back()的用法。我认为pop_back()实际上相当于arr.resize(arr.size()-1),不知对否。
#include <iostream>
#include <climits>
#include <vector>
using namespace std;
class MinStack {
public:
MinStack():minv(INT_MAX) {}
void push(int x) {
if (x<=minv) {
arr.push_back(minv);
minv=x;
}
arr.push_back(x);
}
void pop() {
int tmp=arr.back();
arr.pop_back();
if (tmp==minv) {
minv=arr.back();
arr.pop_back();
}
}
int top() {
return arr.back();
}
int getMin() {
return minv;
}
private:
vector<int> arr;
int minv;
};
int main()
{
MinStack *obj = new MinStack();
obj->push(7);
obj->push(2);
obj->push(3);
obj->push(1);
obj->push(0);
obj->pop();
obj->push(5);
obj->push(4);
obj->push(3);
int param_3 = obj->top();
int param_4 = obj->getMin();
cout<<param_3<<" "<<param_4<<endl;
return 0;
}
dsf