剑指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\n", queue.pop());
86             }
87         }
88         queue.clear();
89     }
90     
91     return 0;
92 }

 

 posted on 2013-11-29 21:34  zhuli19901106  阅读(212)  评论(0编辑  收藏  举报