实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
1.用两个栈实现
入栈:一个栈作为数据栈,一个栈作为最小值栈,往数据栈中直接压入数据,比较此时数据栈栈顶元素和min栈栈顶元素的大小,若min栈的栈顶元素小,则往min栈中压入栈顶元素,若要数据栈栈顶元素小,则压入数据栈栈顶元素。
出栈:数据栈和min栈同时pop
取最小值:取min栈的栈顶元素
//用两个栈实现
template<class T>
class Stack1
{
public:
void Push(T d)
{
sData.push(d);
if (sMin.empty() || sMin.top() > d)
sMin.push(d);
else
sMin.push(sMin.top());
}
void Pop()
{
if (!sData.empty())
{
sData.pop();
sMin.pop();
}
else
return;
}
T& Min()
{
assert(!sMin.empty());
return sMin.top();
}
private:
stack<T> sData; //数据栈
stack<T> sMin; //最小值栈
};
2.用一个栈实现
入栈:min值的确定方法和两个栈时一样,不过数据和min值压入同一个栈,数据先压入,min值后压入。
出栈:pop两次。
取最小值:取栈顶元素值。
//用一个栈实现
template<class T>
class Stack2
{
public:
void Push(T d)
{
if (s.empty() || s.top() > d)
{
s.push(d);
s.push(d);
}
else
{
T tmp = s.top();
s.push(d);
s.push(tmp);
}
}
void Pop()
{
if (!s.empty())
{
s.pop();
s.pop();
}
else
return;
}
T& Min()
{
assert(!s.empty());
return s.top();
}
private:
stack<T> s;
};
push和pop都只进行了常数次,所以时间复杂度为O(1)
使用两个栈实现一个队列
1.保证在整个过程中,一个栈为空,则另外一个栈要么为空,要么有数据,不能出现两个栈同时有数据的情况,这样就可以借助为空的那个栈进行push和pop等操作了。
template<class T>
class Queue1
{
public:
void Push(T d)
{
if (s1.empty() && s2.empty())
{
s1.push(d);
}
else