题目地址:力扣
解法1:可以使用multiset来对元素进行保存,因为multiset总是有序的,因此可以快速得到栈中最小的元素。(由于栈中可能存在相同的元素,因此不能用set,否则删除一个的时候会全部删掉)
class MinStack {
public:
MinStack() {}
void push(int val) {
stk.push(val);
iset.insert(val);
}
// 出栈的时候使用find找到一个实例并且删除
// 若使用参数为值的erase就会把所有的值都删掉
void pop() {
iset.erase(iset.find(stk.top()));
stk.pop();
}
int top() {
return stk.top();
}
int getMin() {
return *iset.cbegin();
}
private:
stack<int> stk;
multiset<int> iset;
};
解法2:辅助栈,主栈和辅助栈共同进退,唯一不同的就是辅助栈保存的是每一次操作后,当前栈中的最小值。因此也可以快速找到最小的元素
class MinStack {
public:
MinStack() {}
void push(int val) {
stk.push(val);
if (min_stk.empty())
min_stk.push(val);
// 辅助栈入栈的时候要看看是当前元素更小还是之前的元素更小
else
min_stk.push(min_stk.top() < val ? min_stk.top() : val);
}
void pop() {
stk.pop();
min_stk.pop();
}
int top() {
return stk.top();
}
int getMin() {
return min_stk.top();
}
private:
stack<int> stk;
stack<int> min_stk;
};
解法3:存差值法
这种方法不需要额外的辅助集合或者辅助栈,只需要维护一个全局最小值即可,但是根据题目的限制,存差值的话如果栈为int型会溢出,因此必须要为long long型。
具体思路:栈中不存真实的val数值,而是val与最小值之间的差值。这样即使出栈,也可以根据差值还原出上一时刻的最小值。而且只要栈中元素为负(差值为负),就说明当前的真实值就是当前的最小值
class MinStack {
public:
MinStack() {}
void push(int val) {
// 若栈空,则把最小值设置为当前值,并且栈压入0(差值为0)
if (stk.empty())
{
min = val;
stk.push(0);
}else {
// 栈不空,则压入当前值与最小值的差值,并且更新最小值
stk.push(val - min);
min = min > val ? val : min;
}
}
void pop() {
// 出栈的时候需要更新最小值
if (stk.top() < 0)
min -= stk.top();
stk.pop();
}
int top() {
// 如果栈顶的值小于0,则说明栈顶的真实值就是最小值
// 如果栈顶的值大于0,则说明栈顶的真实值就是最小值加差值
return stk.top() < 0 ? min : min + stk.top();
}
int getMin() {
return min;
}
private:
stack<long long> stk;
long long min;
};
Accepted
- 31/31 cases passed (16 ms)
- Your runtime beats 93.35 % of cpp submissions
- Your memory usage beats 79.98 % of cpp submissions (15.8 MB)