内卷之源:
https://leetcode-cn.com/problems/min-stack/
题目描述:
* 设计一个支持 push、pop 和 top 操作,并能在 常数时间 内检索到最小元素的栈。
* 说明:
-2^31 <= val <= 2^31 - 1 //int型取值范围
pop、top 和 getMin 操作总是在 非空栈 上调用
push、pop、top 和 getMin 最多被调用 3 * 10^4 次
测试用例:
push(-2) —— 最先入栈的元素在栈底 |
思路分析:
* 对于 push、pop 和 top 操作,最简单的方式就是借助C++标准库的stack容器,均为常数时间复杂度。
* 获取栈中最小元素的办法一般是对栈中所有元素进行一次遍历,显然不符合在“常数时间”内检索到最小元素这一要求。
* 常见的两种方法:
法一:创建两个栈 数据栈 + 辅助栈,数据栈用于响应外部栈操作请求。
每次push操作时,若该元素不大于辅助栈栈顶元素(等于条件用于解决在连续push进数据栈的元素都不小于辅助栈栈顶元素,且有多个元素等于辅助栈栈顶元素的情况),将其同步添加到辅助栈,因此最小元素始终在辅助栈的栈顶。
每次top操作时,辅助栈栈顶元素若与数据栈栈顶元素相同,也同步删除辅助栈栈顶元素。
每次获取栈最小元素,直接返回辅助栈栈顶元素。若辅助栈为空,则数据栈必为空。
法二:创建单个数据栈,每个栈元素包含两个值,一个是当前位置push进的数,另一个则是当前栈中最小的数。(法一的优化版)
将两个value视为一个单元的场合在C++中常用工具pair<>
* 用C实现时,使用单链表构建栈即可。
编程实现(C++):
/*
************************************************************
* @author SLF
* @version V1.0.0
* @date 29-May-2021
************************************************************
*/
#include <iostream>
#include <vector>
#include <utility>
#include <stack>
using namespace::std;
class MinStack {
public:
MinStack()
{//stack默认基于deque实现
;
}
~MinStack() {}
void push(const int val)
{
int min_val = val;
if(!datastack.empty())
{
min_val = datastack.top().second;
if(min_val > val)
{
min_val = val;
}
}
datastack.push({val, min_val});
}
void pop()
{
if(datastack.empty())
{
return;
}
datastack.pop();
}
int top() const
{
if(datastack.empty())
{
return INT32_MAX;
}
return datastack.top().first;
}
int getMin() const
{
if(datastack.empty())
{
return INT32_MAX;
}
return datastack.top().second;
}
private:
stack<pair<int,int>> datastack;
};
class MinStack_Aux {
public:
MinStack_Aux()
{//stack默认基于deque实现
;
}
~MinStack_Aux() {}
void push(const int val)
{
if(auxstack.empty()) //第一次
{
auxstack.push(val);
}
else
{
if(auxstack.top() >= val)
{
auxstack.push(val);
}
}
datastack.push(val);
}
void pop()
{
if(auxstack.empty()) //数据栈和辅助栈不会出现一个为空,而另一个不为空的情况
{
return;
}
if(auxstack.top() == datastack.top())
{
auxstack.pop();
}
datastack.pop();
}
int top() const
{
if(datastack.empty())
{
return __INT32_MAX__;
}
return datastack.top();
}
int getMin() const
{
if(auxstack.empty())
{
return __INT32_MAX__;
}
return auxstack.top();
}
private:
stack<int> datastack;
stack<int> auxstack;
};
int main(void)
{
MinStack stk;
//MinStack_Aux stk;
const vector<vector<int>> test_data = {{-2, 0, -3}, {-2, 0, -2, -3}, {-2, 0, -3, -2}};
const int n = test_data.size();
for(int i = 0; n > i; ++i)
{
cout << "第" << i << "组" << endl;
for(const auto d : test_data[i])
{
stk.push(d);
}
const int m = test_data[i].size() + 1; //题设中已假定 pop、top 和 getMin 操作总是在 非空栈 上调用
for(int j = 0; m > j; ++j)
{
cout << "TOP: " << stk.top() << endl;
cout << "MIN: " << stk.getMin() << endl << endl;
stk.pop();
}
}
return 0;
}
郑重提示:①解题思路非最优,覆盖条件可能不全,仅供练习参考。
②若有更佳思路或疑问,可在评论区留言相互讨论,不亦乐乎。
③本文不允许转载,若认可本文,可点赞收藏关注。