方法一:辅助栈
核心思想:
普通栈的 和
函数的复杂度为
,满足题目要求。但获取栈最小值的
函数需要遍历整个栈,复杂度为
,所以本题的主要目的就在于优化对栈的最小值的获取,这可以通过使用一个具有单调性的辅助栈来实现。
具体思路:
数据栈:数据栈用于存储所有元素,保证函数的正常逻辑。
辅助栈:辅助栈中存储数据栈中所有降序的元素。栈具有先进后出的特点,所以一个值压入栈中后,只要未被弹出,所有在它之后进行压栈的小于该值的元素都不会成为最小值,可以不压入辅助栈,这可以保证辅助栈栈顶即为数据栈中所有数据中的最小值。
函数说明: 压栈时,只有辅助栈为空,或该数值不大于辅助栈栈顶元素,才对辅助栈进行压栈。
出栈时,如果数据栈栈顶元素与辅助栈栈顶元素相等,说明该数值被弹出,也需要同时对辅助栈进行出栈。
核心代码:
class Solution {
private:
stack<int> sk;
stack<int> help;
public:
void push(int value) {
sk.push(value);
//保证辅助栈的单调性
if(help.empty() || value <= help.top()) {
help.push(value);
}
}
void pop() {
//如果辅助栈栈顶值与数据栈栈顶值相等则出栈
if(help.top() == sk.top()) {
help.pop();
}
sk.pop();
}
int top() {
return sk.top();
}
int min() {
return help.top();//辅助栈栈顶既为最小值
}
};复杂度分析:
时间复杂度:,对单个操作,四个函数的时间复杂度均为常数级别
空间复杂度:,最坏情况下,辅助栈也需要存储所有元素,使用
空间
方法二:单个栈
核心思想:
也可以使用单个栈完成功能,但此时的栈不是存储数据,而是存储数据与当前最小值的差值,并另外存储一个最小值
函数说明: :压栈时,当栈为空时,存储最小值,压入差值0。栈不为空时,压入数据与当前最小值的差值,如果差值为负,则更新最小值
:出栈时,如果此时栈顶值为负数,说明此处发生的最小值的变化,需要更新最小值。
:如果栈顶值为负数,说明最小值在此处更新,此时返回最小值即可。如果栈顶值为正数,即为最小值与数据的差值,相加后进行返回
:直接返回存储的最小值即可
核心代码:
class Solution {
private:
stack<long> sk;//记录与最小值差值,由于可能大于INT_MAX,使用long
long tmin;//记录最小值
public:
void push(int value) {
if(sk.empty()) {
//当栈为空,最小值即为当前值,差值为0
sk.push(0);
tmin = value;
} else {
//压入与最小值的差值
sk.push(value - tmin);
if(value < tmin) {
//如果当前值小于最小值,进行更新
tmin = value;
}
}
}
void pop() {
if(sk.top() < 0) {
//差值为负数,说明当前位置最小值发生改变,需要改回该元素压入前的最小值
tmin -= sk.top();
}
sk.pop();
}
int top() {
if(sk.top() < 0) {
return tmin;//此时最小值刚进行更新
} else {
return tmin + sk.top();
}
}
int min() {
return tmin;
}
};复杂度分析:
时间复杂度:,对单个操作,四个函数的时间复杂度均为常数级别
空间复杂度:,只使用了常数个变量



京公网安备 11010502036488号