Description
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
push(x) – Push element x onto stack.
pop() – Removes the element on top of the stack.
top() – Get the top element.
getMin() – Retrieve the minimum element in the stack.
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); –> Returns -3.
minStack.pop();
minStack.top(); –> Returns 0.
minStack.getMin(); –> Returns -2.
My solution:TLE
#include "tree.h"
// 超时!!!!!!
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
vector<int> v;
void push(int x) {
v.push_back(x);
}
void pop() {
v.pop_back();
}
int top() {
return v[v.size() - 1];
}
int getMin() {
int minval = v[0];
for (int i = 0; i < v.size(); i++) {
minval = v[i] < minval ? v[i] : minval;
}
return minval;
}
};
- 我的算法超时
- 不符合题意中关于getMin的描述.题目要求算法时间复杂度在O(1),实际上我这个是O(n),当n很大时,这也是很大的开销,真实的业务场景(针对性的数据库设计)可能不限于求min,但思路是类似的 : 空间换取时间,将常用的操作特殊处理,而非每次遍历.
Discuss
class MinStack {
private:
stack<int> s1;
stack<int> s2;
public:
void push(int x) {
s1.push(x);
if (s2.empty() || x <= getMin()) s2.push(x);
}
void pop() {
if (s1.top() == getMin()) s2.pop();
s1.pop();
}
int top() {
return s1.top();
}
int getMin() {
return s2.top();
}
};
自己曾想到设定两个值保存oldmin,curmin这样子的操作,但是pop之后,应该具有历史可回溯性,从这个角度也应该想到,要用更大的存储空间来回溯历史,即上述方法的第二个stack.
————————————-20170724—————————————–
根据开辟第二个stack思想,自己重新写了一遍代码,用stack2记录到目前为止的minval,大小同stack1.size.
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
stack<int> s1, s2;
void push(int x) {
s1.push(x);
if (!s2.empty()) s2.push(min(x, s2.top()));
else s2.push(x);
}
void pop() {
s1.pop();
s2.pop();
}
int top() {
return s1.top();
}
int getMin() {
return s2.top();
}
};
上述代码仍和Discuss代码有所差距,在于没有对stack做优化,虽然简单易理解,实际上,stack2.size和stack1.size一样大,空间复杂度冗余.
同Discuss代码比较,stack2.push时候需要check一下,如果当前值<=minval,就s1/s2都push,否则stack2维持不变.[动态规划思想.]
注意:<=一定不要写成<