1.题目
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)
)。
2.我的题解
首先用一个STL
标准栈存储数值,记为数值栈。
再用一个STL
标准栈存储最小值,记为最小值栈。注意:
- 最小值栈不仅要包含当前的最小值,还要包括弹出数值栈任意值之后的最小值。
- 如果入栈的值更小一些,那么最小值栈就要进行更新操作,如果入栈的值更大一些,那么最小值栈不必操作。
- 时间复杂度:
O(1)
,空间复杂度:O(n)
。
class Solution {
stack<int> value_s;//数值栈
stack<int> min_s;//最小值栈
public:
void push(int value) {
value_s.push(value);
if(min_s.empty() || min_s.top()>=value)min_s.push(value);
}
void pop() {
if(min_s.top()==value_s.top())min_s.pop();
value_s.pop();
}
int top() {
return value_s.top();
}
int min() {
return min_s.top();
}
};
3.别人的题解
链接:https://www.nowcoder.com/questionTerminal/4c776177d2c04c2494f2555c9fcc1e49?answerType=1&f=discussion
来源:牛客网
竟有时空复杂度均为O(1)
的解法,真真膜拜。
原理是数据冗余,即当前数据中已经包含了前面数据的最小值,举个例子。
入栈顺序 | top | min | diff | 关系 |
---|---|---|---|---|
4 | 4 | 4 | 0=4-4 | 4=4+(0) |
5 | 5 | 4 | 1=5-4 | 5=4+(1) |
6 | 6 | 4 | 2=6-4 | 6=4+(2) |
3 | 3 | 3 | -1=3-4 | 3=4+(-1) |
2 | 2 | 2 | -1=2-3 | 2=3+(-1) |
1 | 1 | 1 | -1=1-2 | 1=2+(-1) |
如表,假设我们存储了当前的最小值、栈顶值以及diff
,那么我们就可以推出以前的所有最小值和栈顶值。
入栈:
压缩:将要入栈的元素value减去当前最小值min,得到一个差值diff,只存储该差值;
更新:如果入栈的元素value比当前最小值min小,则要更新最小值:min=value;
初始:第一次入栈比较特殊,因为此时的min变量并没有值,所以令:min=value;
top:top当然设置为value;
出栈:
更新:如果栈中存储的差值diff是负数,说明出栈的元素是当前最小值min,需要把min值更新为上一个最小值min = min - diff,否则,出栈的元素不是最小值,则不对min变量做任何操作;
还原:如果栈中存储的差值diff是正数,说明 top = min + diff,否则,说明top元素本身是最小值 top = min;
顺序:先更新min,再利用min更新top;
class Solution {
stack<int> stack_s;//差值栈
int top_,min_;
public:
void push(int value) {
if(stack_s.empty())
min_=value;
stack_s.push(value-min_);
min_=min_>value?value:min_;
top_=value;
}
void pop() {
if(!stack_s.empty()){
if(stack_s.top()<0)min_=min_-stack_s.top();
stack_s.pop();
if(!stack_s.empty())
top_=top_+(stack_s.top()>0?stack_s.top():0);
}
}
int top() {
return top_;
}
int min() {
return min_;
}
};
4.总结与反思
(1)压缩还原法(数据冗余)。
来源:CSDN
作者:永封
链接:https://blog.csdn.net/weixin_43951240/article/details/104062861