232. 用栈实现队列

232. Implement Queue using Stacks

使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

1. 第一个回合 题目理解 必须满足队列的 FIFO特征

我想到以前做个类似选择题,,但是忘记了 ,忘记里面关键地方是什么?
思路中断

后记:
寻找的找个题目,
假设栈的输入序列为1、2、3、...、n,设计算法求出所有可能的出栈序列(合法序列)。
比如 n = 4,出栈序列可能有1 2 3 4 , 1 2 4 3 , 1 4 3 2 , 1 3 4 2等等
关键点
来了一批数据,入栈n个元素,可能有1--n个出栈方式
来了一批数据,入栈m个元素,可能有1--m个出栈方式
序列1、2、3、...、n 可以拆分不同的序列

image.png

2. 第二次尝试 用2个stack来模拟队列的基本操作

入队列,和出队列,第一个存储,第二个输入出
但是情况

输入序列: 1 2 3 4 5,
第一次:1 2 3 入栈 12 出栈
第二次:4 5 入栈 3怎么出栈?

这是很明显了,在第二次入栈之前,必须stack2数据完全出栈,但是用户可能不按照你操作来。思路中断,无法进行下去了。
你假设 stack2 回到stack1这个点,你想到了,但是无法作为算法进行描述

后记:


image.png

3. 第三次尝试

队列入栈

  1. 如果stack2 为null ,直接入栈stack1
    2 如果stack2 不会空,说明,第一次插入,还有数据,需要倒回。

code

/**
执行用时: 28 ms, 在Implement Queue using Stacks的C++提交中击败了
9.45% 的用户
push time:o(n)
pop time: o(n) 
**/
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {
        
        m_total =0;
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        
       m_total++;
       //
       if(!m_output.empty()){
           while(!m_output.empty()){
               m_input.push(m_output.top());
               m_output.pop();
           }
         }
        
        m_input.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        m_total--;
        int val=peek();
        m_output.pop();
       return val;
    }
    
    /** Get the front element. */
    int peek() {
       //序列:第一个入队列的,需要第一个出队列  
      if (m_output.empty())
      {
        if(m_output.empty()){
           while(!m_input.empty()){
               m_output.push(m_input.top());
               m_input.pop();
           }
           }
      }
     return   m_output.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        
        return m_total ==0;
    }
    
    private:
    stack m_input; //入队列操作
    stack m_output;//出队列操作
    int m_total;
};

优化 pop o(n)-o(1),但是push 可能比较繁琐,不适合频繁插入

/**
time:
push o(n)
pop o(1)
执行用时: 0 ms, 在Implement Queue using Stacks的C++提交中击败了100.00% 的用户
**/
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {
        m_total =0;
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        
       m_total++;
       //
       if(!m_output.empty()){
           while(!m_output.empty()){
               m_input.push(m_output.top());
               m_output.pop();
           }
         }
        
        m_input.push(x);
        
           while(!m_input.empty())
           {
               m_output.push(m_input.top());
               m_input.pop();
           }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        m_total--;
        int val=peek();
        m_output.pop();
       return val;
    }
    
    /** Get the front element. */
    int peek() {
       //序列:第一个入队列的,需要第一个出队列  

     return   m_output.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        
        return m_total ==0;
    }
    
    private:
    stack m_input; //入队列操作
    stack m_output;//出队列操作
    int m_total; //记录大小
};

测试

  • test 1
    序列 A B C| D
    入队列 A B C. 出队列 A B ,
    在入队列 D.
    ------2018/12/23

你可能感兴趣的:(232. 用栈实现队列)