AcWing 41. 包含min函数的栈(仅使用一个栈)
原题链接
简单
作者:
wzc1995
,
2019-12-03 01:29:38
,
所有人可见
,
阅读 2937
算法
(栈) $O(n)$
- 两个栈的方法已经烂大街了,这里提供仅用一个栈的方法。
- 我们只开一个普通栈和一个变量
min_value
记录最小值。栈中存放当前元素与当前最小值的差值。
- 进栈时,如果栈为空,则插入当前元素,然后更新
min_value
。如果栈不空,则插入 x - min_value
,然后更新 min_value
。
- 出栈时,如果栈顶元素小于 0,则说明栈顶元素为当前最小值,需要回滚上一次的最小值。出栈。
- 取栈顶元素时,如果栈中只有一个元素,直接返回。否则,如果栈顶元素大于 0,则说明栈顶不是当前最小值,通过差值计算找到最小值;如果栈顶元素小于 0,则直接返回最小值。
- 返回最小值时,直接返回
min_value
。
- 注意,整数运算有可能溢出,需要用
long long
。
时间复杂度
空间复杂度
C++ 代码
class MinStack {
public:
/** initialize your data structure here. */
#define LL long long
stack<LL> st;
LL min_value;
MinStack() {
}
void push(int x) {
if (st.empty()) {
st.push(x);
min_value = x;
} else {
st.push(x - min_value);
min_value = min(min_value, (LL)(x));
}
}
void pop() {
if (st.top() < 0)
min_value -= st.top();
st.pop();
}
int top() {
if (st.size() == 1)
return st.top();
else if (st.top() > 0)
return min_value + st.top();
else
return min_value;
}
int getMin() {
return min_value;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
极致的状态压缩 帅 感觉这里的思路 有种信息论的味道
大佬,这里题目中不是说操作命令总数为[0,100],想请问下你是怎么推出整数运算可能会溢出呢?
大佬你好,想问一下push的时候 为啥不先更新min再push呢? 就是先更新min_value 再进行push(x-min_value)
是因为这样写的话 后续的getmin pop 不好写吗
只要操作可逆,都是可以的,你可以尝试一下
第五句话没有理解,为什么取栈顶元素的时候,如果栈中只有一个元素,直接返回。否则,如果栈顶元素大于 0,则说明栈顶不是当前最小值,通过差值计算找到最小值;如果栈顶元素小于 0,则直接返回最小值。
这里取栈顶元素为什么要取最小值??
当前栈顶就两种情况,一种是当前最小值,一种不是当前最小值。由于栈里记录的是与当前最小值的差值,所以根据差值的正负来区分并“恢复计算出”当前栈顶的值
很牛的方法,学到了
为什么stack栈底元素要放x本身呀,感觉放差值也可以的样子
好吧只能在top省了一个if
看了很多题解都是两个栈,只能说wzcNB
就喜欢这样的:)
太强了
学习到了,谢谢分享。
如果pop刚好是
min_value
,回滚上一次的最小值, 怎么理解min_value -= st.top();
top
刚好是最小值,则top
存的就是 0。学习了