剑指Offer - 九度1512 - 用两个栈实现队列
2013-11-29 21:23
题目描述:

用两个栈来实现一个队列,完成队列的Push和Pop操作。
队列中的元素为int类型。

输入:

每个输入文件包含一个测试样例。
对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数。
接下来的n行,每行输入一个队列操作:
1. PUSH X 向队列中push一个整数x(x>=0)
2. POP 从队列中pop一个数。

输出:

对应每个测试案例,打印所有pop操作中从队列pop中的数字。如果执行pop操作时,队列为空,则打印-1。

样例输入:
3
PUSH 10
POP
POP
样例输出:
10
-1
题意分析:
  用两个栈实现一个队列。栈(stack)的特点是先进后出,是反的;而队列(queue)的特点是先进先出,是正的。因此用两个栈,反两次就能正过来。接下来咱看看怎么个反法。
  咱们从例子入手:四个数1, 2, 3, 4进入队列,如果这时想pop的话,应当是1出队。两个栈s1,s2如下(左边代表栈顶):
    s1 = [4, 3, 2, 1]
    s2 = []
  但是1, 2, 3, 4进栈时,栈顶元素是4。要想取出1的话,必须先pop掉4,3,2。pop出来的元素又不能扔掉,就扔另一个栈里去吧,于是就成了这样:
    s1 = [1]
    s2 = [2, 3, 4]
  因为进站后顺序又反了一次,所以s2中存储的顺序就是正确的出队顺序,这时直接从s1中pop出元素‘1’即可。如果要继续pop元素的话,s2栈不为空,直接pop就能得到正确的结果。
  于是有了下面的思路:
     1. 初始化s1、s2为空。
     2. 当进队时,直接将元素push进s1。
     3. 当出队时,
       若s2不为空,直接pop s2的元素即可出队;
       若s2为空,则将s1中元素pop出来,并push到s2中,直到s1只剩一个元素。剩的那个元素pop出来就是出队的元素。
       当然,两个栈都为空的话pop操作是无效的。
  这题应该算是很经典的面试题了,挺巧妙的。以下是ac的代码。push入队时间复杂度O(1),pop出队时间复杂度O(1)或O(n),均摊下来仍是O(1)。
 // 651425    zhuli19901106    1512    Accepted    点击此处查看所有case的执行结果    1184KB    1415B    70MS
//
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std; class MyQueue{
public:
MyQueue()
{
} ~MyQueue()
{
while(!s1.empty()){
s1.pop();
}
while(!s2.empty()){
s1.pop();
}
} void push(int n)
{
s1.push(n);
} int pop()
{
if(s1.size() <= && s2.size() <= ){
// The queue is empty, return -1 to signal an error.
return -;
}
if(s2.size() > ){
int res = s2.top();
s2.pop();
return res;
}else{
int res;
while(s1.size() > ){
res = s1.top();
s1.pop();
s2.push(res);
}
res = s1.top();
s1.pop();
return res;
}
} void clear()
{
while(s1.size() > ){
s1.pop();
}
while(s2.size() > ){
s2.pop();
}
} int size()
{
return s1.size() + s2.size();
}
private:
stack<int> s1, s2;
}; int main()
{
char s[];
int n;
int i;
int tmp;
MyQueue queue; while(scanf("%d", &n) == ){
for(i = ; i < n; ++i){
scanf("%s", s);
if(strcmp(s, "PUSH") == ){
scanf("%d", &tmp);
queue.push(tmp);
}else if(strcmp(s, "POP") == ){
printf("%d\n", queue.pop());
}
}
queue.clear();
} return ;
}

剑指Offer - 九度1512 - 用两个栈实现队列的更多相关文章

  1. 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先

    剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...

  2. 剑指Offer - 九度1519 - 合并两个排序的链表

    剑指Offer - 九度1519 - 合并两个排序的链表2013-11-30 22:04 题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.(hi ...

  3. 剑指offer第二版-9.用两个栈实现队列

    描述:使用两个栈实现一个队列.队列中实现尾部插入和头部删除函数. 思路:stack1负责插入,stack2负责弹出,如果stack2为空了,将stack1的元素依次弹出并存放到stack2中,之后对s ...

  4. 剑指offer【05】- 用两个栈实现队列(java)

    题目:用两个栈实现队列 考点:栈和队列 题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路:每次psuh是时先将stack2清空放入stck1(保 ...

  5. 剑指offer(9)——用两个栈实现队列

    题目: 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 思路: 首先定义两个栈stack1. ...

  6. JS 剑指Offer(六) 用两个栈实现队列

    题目:用两个栈实现队列,实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数,若队列中没有元素deleteHead返回-1 分析:在队列的尾部插入 ...

  7. 剑指Offer:面试题7——用两个栈实现队列(java实现)

    题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 首先定义两个栈 Stack<Integer> stack1 = new Stack<I ...

  8. 《剑指Offer》面试题-用两个栈实现队列

    题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100 ...

  9. 剑指offer(5)用两个栈实现队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 题目分析 栈是先进后出,队列是先进先出,因此两个栈,一个用来push,一个用来pop,同时注意下两个栈不 ...

随机推荐

  1. 【转】Android UI开发第二十四篇——Action Bar

    Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式.在大多数的情况下,当你需要突出展现用户行为或全局导航的activity中使用action bar,因为acti ...

  2. 今天 小小收获, 看了 sam Xiao 的好帖子 明白了 泛型委托 的 意思。

    Func<int,int,int> cAdd1 = (int x, int y) => { return x + y; }; int result= aAdd1(1,2); cons ...

  3. P3901 【数列找不同】

    这个题我们可以使用树状数组做 啥? 树状数组? 那个不是维护前缀和的东西吗? 各位看官,让我慢慢道来. 首先我们可以想到,对于一个询问$ [l,r] \(,只有\)[1,r]$中的数可能对这个询问有影 ...

  4. 多重网格方法(Multigridmethod)

    原文链接 多重网格方法是解微分方程的方法.这个方法的好处是在利用迭代法收敛结果的时候速度特别快.并且,不管是否对称,是否线性都无所谓.它的值要思想是在粗糙结果和精细结果之间插值. 前面介绍了Gauss ...

  5. Python测量时间,用time.time还是time.clock

    在计算机领域有多种时间.第一种称作CPU时间或执行时间,用于测量在执行一个程序时CPU所花费的时间.第二种称作挂钟时间,测量执行一个程序时的总时间.挂钟时间也被称作流逝时间或运行时间.与CPU时间相比 ...

  6. 关于新项目上传远程库报错 non-fast-forward

    已有项目上传远程库会报错 non-fast-forward 首先使用命令行 git pull origin master --allow-unrelated-histories 之所以使用这个命令,是 ...

  7. 一篇SSM框架整合友好的文章(二)

    上一篇讲述了DAO 层,mybatis实现数据库的连接,DAO层接口设计,以及mybtis和spring的整合.DAO层采用接口设计方式实现,接口和SQL实现的分离,方便维护.DAO层所负责的仅仅是接 ...

  8. JQuery实现子级选择器

    效果图如下: HTML代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  9. LeetCode979. 在二叉树中分配硬币

    问题:979. 在二叉树中分配硬币 给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们可以选择两个相邻的 ...

  10. javascript遍历方法总结

    forEach 循环 JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.lengt ...