• 剑指Offer


    剑指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)。
     1 // 651425    zhuli19901106    1512    Accepted    点击此处查看所有case的执行结果    1184KB    1415B    70MS
     2 // 201311142215
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <stack>
     6 using namespace std;
     7 
     8 class MyQueue{
     9 public:
    10     MyQueue()
    11     {
    12     }
    13     
    14     ~MyQueue()
    15     {
    16         while(!s1.empty()){
    17             s1.pop();
    18         }
    19         while(!s2.empty()){
    20             s1.pop();
    21         }
    22     }
    23     
    24     void push(int n)
    25     {
    26         s1.push(n);
    27     }
    28     
    29     int pop()
    30     {
    31         if(s1.size() <= 0 && s2.size() <= 0){
    32             // The queue is empty, return -1 to signal an error.
    33             return -1;
    34         }
    35         if(s2.size() > 0){
    36             int res = s2.top();
    37             s2.pop();
    38             return res;
    39         }else{
    40             int res;
    41             while(s1.size() > 1){
    42                 res = s1.top();
    43                 s1.pop();
    44                 s2.push(res);
    45             }
    46             res = s1.top();
    47             s1.pop();
    48             return res;
    49         }
    50     }
    51     
    52     void clear()
    53     {
    54         while(s1.size() > 0){
    55             s1.pop();
    56         }
    57         while(s2.size() > 0){
    58             s2.pop();
    59         }
    60     }
    61     
    62     int size()
    63     {
    64         return s1.size() + s2.size();
    65     }
    66 private:
    67     stack<int> s1, s2;
    68 };
    69 
    70 int main()
    71 {
    72     char s[100];
    73     int n;
    74     int i;
    75     int tmp;
    76     MyQueue queue;
    77     
    78     while(scanf("%d", &n) == 1){
    79         for(i = 0; i < n; ++i){
    80             scanf("%s", s);
    81             if(strcmp(s, "PUSH") == 0){
    82                 scanf("%d", &tmp);
    83                 queue.push(tmp);
    84             }else if(strcmp(s, "POP") == 0){
    85                 printf("%d
    ", queue.pop());
    86             }
    87         }
    88         queue.clear();
    89     }
    90     
    91     return 0;
    92 }
  • 相关阅读:
    HDU 树型dp
    NOIP模拟 Math
    HTML5本地存储LocalStorage和sessionStorage
    数据结构与算法第一章答案
    堆和队列的应用之——简单计算器
    HITCS-LAB1 Linux 下C工具的应用
    cs:app 第二章homework(已完结)
    vim使用小结(1)
    学术英语写作(1)
    linux基础(2)
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3450341.html
Copyright © 2020-2023  润新知