题目:设计一个栈类型,使得在该栈类型中有一个函数min可以得到栈的最小元素,要求这个栈的push、pop、min都是O(1)。
分析:
1. 栈的性质是先进后出,因此一般情况下栈的push、pop的时间是O(1),但是要求栈的min必须要枚举整个栈,时间复杂度为O(n)
2. 题目要求设计一个栈在O(1)的时间内找到min,我们要想到一个方法来满足,先看一个例子
3. 从下面的表中我们可以很清楚的看到,我么需要维护一个保存min的栈,并且这个栈和我们的数据栈是一起变化的,因此我们可以利用两个栈来模拟实现这个过程
操作 |
栈的元素(左边栈顶) |
最小值 |
|
第一次 |
Push 5 |
5 |
5 |
第二次 |
Push 6 |
6 5 |
5 |
第三次 |
Push 4 |
4 6 5 |
4 |
第四次 |
Push 7 |
7 4 6 5 |
4 |
第五次 |
Push 9 |
9 7 4 6 5 |
4 |
第六次 |
Pop |
7 4 6 5 |
4 |
第七次 |
Pop |
4 6 5 |
4 |
第八次 |
Pop |
6 5 |
5 |
第九次 |
Pop |
5 |
5 |
4. 示例代码
//实现含有min的栈类模板
template <typename T>
class Stack{
public:
Stack(void);
~Stack(void){}
//声明函数
void Push(const T& value);
void Pop(void);
T Min(void);
private:
stack<T> dataStk;
stack<T> minStk;
};
//实现构造函数
template <typename T> Stack<T>::Stack(void){
//清空两个栈
while(!dataStk.empty()){
dataStk.pop();
}
while(!minStk.empty()){
minStk.pop();
}
}
//实现Push
template <typename T> void Stack<T>::Push(const T& value){
dataStk.push(value);
//如果是空栈直接插入,不能通过取栈顶元素比较
if(minStk.empty()){
minStk.push(value);
}
else{
T minValue = minStk.top();
if(minValue > value){
minValue = value;
}
//插入到minStk中
minStk.push(minValue);
}
}
//实现Pop函数
template <typename T> void Stack<T>::Pop(void){
//如果是空栈报异常
if(dataStk.empty()){
throw exception("error");
}
else{
dataStk.pop();
minStk.pop(); //同时删除minStk栈顶元素
}
}
//实现Min函数
template <typename T> T Stack<T>::Min(void){
//如果空栈返回异常
if(minStk.empty()){
throw exception("error");
}
else{
return minStk.top();
}
}