一:实现一个栈,要求实现Push,Pop,Min的操作时间复杂度是O(1);
我们知道栈的特点是后进先出
Push和Pop的操作都是O(1);要返回最小值Min的时间复杂度是O(1),需要一个辅助栈,用来保存最小值;
思想:
有两个栈s1和s2,其中s2是辅助栈(用来保存最小值的栈)
1:先把元素压入栈1,在比较压入的元素与保存最小值的(栈2)的栈顶元素的大小,始终保持,最小值在栈2.
2:出栈时,比较栈1辅助栈2的栈顶元素,相等同时出栈,不相等,栈1出栈。
3:最小值,取栈2的栈顶元素;
4:实现:
template<class T>
class Stack
{
public:
//先把元素压入栈1,比较压栈的元素与保存最小值栈的栈顶元素
void Push(const T&x)
{
_st.push(x);
if (_min.empty() || x <= _min.top())
{
_min.push(x);
}
}
void Pop()
{
//栈顶元素相等
if (_st.top() == _min.top())
{
_st.pop();
_min.pop();
}
//不相等
_st.pop();
}
int Min()
{
return _min.top();//取栈顶元素
}
protected:
stack<T> _min;
stack<T> _st;
};
int main()
{
Stack<int> s;
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Min();
s.Pop();
s.Pop();
s.Pop();
system("pause");
return 0;
}
二:使用两个栈实现一个队列
我们知道队列的操作是先进先出,而栈的操作是后进先出;如何实现呢?用两个栈;一个栈作为入队,一个栈作为出队;
思路:
入队时,把元素压入s1;
出队时,把s1的元素向倒入s2,将s2的栈顶元素弹出作为出队元素,之后将s2的剩余元素,逐个倒回s1;
方法一:
在出队时,加个s1的元素,逐个倒入s2时,s1栈底的元素不用倒入,课直接弹出作为出队元素,这样减少一次压栈开销;
方法二:
入队列时:先判断s1是否为空,若不为空,说明所有原素都在s1,将入队元素直接压入s1,若为空,将s2的元素倒回s1,再把s1的元素入队;
出队列时:s2不为空,把栈s2的栈顶元素直接弹出并且出队,否则把s1元素全部倒入s2,再把栈底元素弹出并且出队;
方法三:
入队列时,元素压入s1;
出队列时,判断s2是否为空,不为空,直接弹出栈顶元素;若为空,则将s1的元素逐个倒入s2中,把最后一个元素弹出并且出队;
这里我们以方法三实现:
template<class T>
struct Queue
{
public:
void Push(const T&x )
{
s1.push(x);
}
void Pop()
{
//s2不为空把元素直接弹出,否则把s1的元素压入到s2中,再弹出s2的栈顶元素
//s2为空
if (s2.empty())
{
//s1不为空
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
//s2不为空,元素直接弹出
s2.pop();
}
void Size()
{
return s1.size() + s2.size();
}
void Empty()
{
return s1.empty() && s2.empty();
}
protected:
stack<T>s1;
stack<T>s2;
};
int main()
{
Queue<int> q;
q.Push(1);
q.Push(2);
q.Push(3);
q.Push(4);
q.Pop();
q.Pop();
q.Pop();
q.Pop();
system("pause");
return 0;
}
三:两个队列实现一个栈
1:入栈时:
判断q1和q2都为空,往q1中压入元素;q2为空,q1不为空,q1中压入元素;q2不为空,q1为空,q2中压入元素;
2:出栈时:
(1)判断当前队列中队头元素是否和队尾元素相等;相等直接出栈;不相等,把q1中的元素逐个压到q2中;
(2)q2中的元素再逐个“倒回”给q1,再判断一次,当前队列中队头元素是否和队尾元素相等。若相等直接出栈;
3:实现
template<class T>
class Stack
{
public:
Stack()
{}
~Stack()
{}
void Push(const T&x)
{
//如果队列1和2都为空
if (_qe.empty() && _tmp.empty())
{
_qe.push(x);
}
//队列1不为空,队列2为空
else if (!_qe.empty())
{
_qe.push(x);
}
//队列1为空,队列2不为空
else
{
_tmp.push(x);
}
}
//出栈
T Pop()
{
T t;
if (_tmp.empty() && _qe.empty())
{
return NULL;
}
else
{
if (!_qe.empty())
{
while (_qe.front() !=_qe.back())
{
_tmp.push(_qe.front());
_qe.pop();
}
_qe.pop();
}
//辅助队列不为空
if (!_tmp.empty())
{
while (_tmp.front() != _tmp.back())
{
_qe.push(_tmp.front());
_tmp.pop();
}
_tmp.pop();
}
}
}
protected:
queue<T> _qe;
queue<T>_tmp;
};
int main()
{
Stack<int> s;
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Pop();
s.Pop();
s.Pop();
s.Pop();
system("pause");
return 0;
}