题目:设计一个栈类型,使得在该栈类型中有一个函数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();
}
}