Implement the following operations of a queue using stacks.
- push(x) -- Push element x to the back of queue.
- pop() -- Removes the element from in front of queue.
- peek() -- Get the front element.
- empty() -- Return whether the queue is empty.
- You must use only standard operations of a stack -- which means only
push to top
,peek/pop from top
,size
, andis empty
operations are valid. - Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
- You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
Subscribe to see which companies asked this question
队列是先进先出,新压入的元素在队尾;栈是先进后出,新压入的元素在栈顶;两次先进后出即是先进先出
考虑用两个栈实现队列的效果:
栈s2执行完任何操作始终有序,s2就是队列的效果,栈s1辅助s2成为有序。
压入时:先将s2的元素全部压入s1,使s2空,再将元素x压入栈s1,再按照顺序全部压入栈2,这样s2就有序。
删除时:因为s2有序,所以直接将s2的栈顶弹出
获取队首:因为s2有序,直接获取s2栈顶元素
是否为空?判断s2是否为空即可
class Queue {
public:
// Push element x to the back of queue.//压到队列尾部
void push(int x) {//此函数将花费大量时间
while(!s2.empty())
{
int val=s2.top();
s2.pop();
s1.push(val);
}
s1.push(x);
while(!s1.empty())
{
int val=s1.top();
s1.pop();
s2.push(val);
}
}
// Removes the element from in front of queue.//从队列前面删除元素
void pop(void) {
s2.pop();
}
// Get the front element.//获取队首元素
int peek(void) {
return s2.top();
}
// Return whether the queue is empty.//队列是否为空
bool empty(void) {
return s2.empty();
}
private:
stack<int> s1;//辅助栈
stack<int> s2;//执行栈,将模拟队列效果
};
别人家的算法思想:
使用两个栈,一个栈用来保存插入的元素(不是队列的顺序),另外一个栈用来执行pop或top操作(已经是队列的顺序)。
压入元素到头:压入到pushStack栈即可,里面的数据暂时不是队列顺序
删除队首元素:pushStack的底部即是队首,全部弹出到popStack栈,再删除popStack栈首即可
获取队首元素:pushStack的底部即是队首,全部弹出到popStack栈,再获取popStack栈首元素即可
队列是否为空:显然两个栈同时为空时,即队列为空
具体如下:
每当执行pop或top操作时检查另外一个栈是否为空,如果为空,将第一栈中的元素全部弹出并插入到第二个栈中,再将第二个栈中的元素弹出即可。需要注意的是这道题的编程时有一个技巧,可以使用peek来实现pop,这样可以减少重复代码。编程时要能扩展思维,如果由于pop函数的声明再前面就陷入用pop来实现peek的功能的话就会感觉无从下手了。
class Queue {
public:
// Push element x to the back of queue.
void push(int x) {
pushStack.push(x);
}
// Removes the element from in front of queue.
void pop(void) {
peek();//这里可以使用peek进行两个栈之间元素的转移从而避免重复代码
popStack.pop();
}
// Get the front element.
int peek(void) {
if(popStack.empty())
{
while(!pushStack.empty())
{
popStack.push(pushStack.top());
pushStack.pop();
}
}
return popStack.top();
}
// Return whether the queue is empty.
bool empty(void) {
return pushStack.empty()&&popStack.empty();
}
private:
stack<int> pushStack;//数据被插入到这个栈中
stack<int> popStack;//数据从这个栈中弹出
};
注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!
原文地址:http://blog.youkuaiyun.com/ebowtang/article/details/50443794
原作者博客:http://blog.youkuaiyun.com/ebowtang