问题描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为 O ( 1 ) O(1) O(1))。
求解思路
首先,考虑到最小元素和时间复杂度是 O ( 1 ) O(1) O(1)的要求,应该想到找一个变量来存储最小元素。但是,这样做有一个缺陷,如果最小元素出栈了,就无法找到第二小的元素了。因此,想到使用一个辅助栈来解决该问题。辅助栈的作用可以看成一个游标,存储了数据栈一定区间范围内最小的元素。
可以这么理解,如果从栈底向栈顶的顺序看去,假设辅助栈不空的情况,那么辅助栈的的两个元素之间对应数据栈的元素,都应该大于辅助栈两个元素中的第一个。给出一个简单的实例,左侧是栈顶,右侧是栈底
AUX:
A
2
A
1
A_{2} \ A_{1}
A2 A1
Data:
A
n
B
m
B
m
−
1
⋯
B
1
A
1
A_{n} \ B_{m} \ B_{m-1}\cdots B_{1}\ A_{1}
An Bm Bm−1⋯B1 A1
那么,
A
1
<
{
B
1
,
⋯
 
,
B
m
}
A_{1}\lt \{B_{1},\cdots,B_{m}\}
A1<{B1,⋯,Bm},且
A
n
<
A
1
A_{n}\lt A_{1}
An<A1
或者Data的区间全是一段相等的元素:
AUX:
A
2
A
1
A_{2} \ A_{1}
A2 A1
Data:
A
2
A
1
A_{2} \ A_{1}
A2 A1
因此需要有下面的规则控制辅助栈:
- 入栈操作:
- 数据栈为空,那么数据栈和辅助栈都要加入第一个数据。
- 数据栈不空,如果当前入栈的元素小于等于辅助栈的栈顶元素,则加入辅助栈
- 出栈操作:
- 如果数据栈栈顶的元素等于辅助栈顶的元素, 则辅助栈出栈
- 否则不操作
AC代码
class Solution {
public:
void push(int value) {
if(DataS.empty()) {
AuxS.push(value);
// cout << "A push" << endl;
} else if(AuxS.top() >= value) { // 注意这里的等号
AuxS.push(value);
// cout << "A push" << endl;
}
DataS.push(value);
}
void pop() {
if(AuxS.top() == DataS.top()) {
AuxS.pop();
// cout << "A pop" << endl;
}
DataS.pop();
}
int top() {
return DataS.top();
}
int min() {
return AuxS.top();
}
stack<int>DataS; // 数据栈
stack<int>AuxS; // 辅助栈
};