【剑指Offer-栈和队列】面试题9:用两个栈实现队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路
假设有两个栈stack1和stack2。我们向stack1中依次压入3个元素:a,b,c。队列是先进先出的,所以我们想让a先出栈,但此时c在栈顶。这时可以利用另一个栈stack2,将stack1中的元素依次弹出后并按照弹出顺序压入到stack2中,则a在stack2的栈顶,弹出即可模拟出队列。当有新的元素进入时,依然压入stack1。
总结一下:stack1只用来插入元素,stack2只用来删除元素。
插入元素:
- 直接将元素插入 stack1 即可;
删除元素:
- 如果 stack2 不为空,则弹出 stack2 的栈顶元素;
- 否则,如果 stack1 不为空,则将 stack1 中的元素弹出并压入 stack2,返回 stack2 的栈顶元素;
代码如下:
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.empty()){
while(!stack1.empty()){
int top = stack1.top();
stack1.pop();
stack2.push(top);
}
}
int top = stack2.top();
stack2.pop();
return top;
}
private:
stack<int> stack1;
stack<int> stack2;
};
拓展:使用两个队列实现一个栈
假设有两个队列q1和q2。初始时队列都为空,我们不妨向q1中压入元素a,b,c。由于栈是后进先出,所以c应该出栈,但c这时在q1的队尾。可以利用q2,我们将a,b出队列后压入q2(q1弹出到只剩一个元素)中,现在q1中只剩下了c,将c出队列返回即可(这一点和使用两个栈实现队列不同,两个栈实现队列中,栈中元素要全部弹出,而这里还剩一个)。此时,q1为空,q2非空。下一个要出栈的元素是b,而b在q2的队尾,同样地,我们将q2弹出到只剩一个元素,然后将弹出的元素a放入空队列q1中。将q2中剩余的一个元素b出队列返回即可。当入栈时,如果哪个队列非空就放进哪个队列。
代码如下:
#include <iostream>
#include <queue>
using namespace std;
class Stack
{
private:
queue<int> q1, q2;
public:
void push(int v)
{
if(q1.empty() && q2.empty())
q1.push(v);
else if(!q1.empty())
q1.push(v);
else q2.push(v);
}
int pop()
{
int ans = -1;
if(q1.empty())
{
int s = q2.size();
while(s>1){
int t = q2.front();
q2.pop();
q1.push(t);
s--;
}
ans = q2.front();
q2.pop();
}
else if(q2.empty())
{
int s = q1.size();
while(s>1){
int t = q1.front();
q1.pop();
q2.push(t);
s--;
}
ans = q1.front();
q1.pop();
}
return ans;
}
};
int main()
{
Stack* s = new Stack();
s->push(1);
s->push(2);
cout<<s->pop()<<endl;
s->push(3);
cout<<s->pop()<<endl;
cout<<s->pop()<<endl;
s->push(4);
s->push(5);
cout<<s->pop()<<endl;
s->push(6);
cout<<s->pop()<<endl;
cout<<s->pop()<<endl;
return 0;
}
输出:
2
3
1
5
6
4