剑指 Offer 09. 用两个栈实现队列 && leetcode225.用队列实现栈

发布时间 2023-04-13 23:16:11作者: luxiayuai

 剑指 Offer 09. 用两个栈实现队列 

class CQueue {
private:
    stack<int> inStack, outStack;
    void in2out(){
        //这里必须是while循环,如果是if判断,则输出栈日常只有一个值,没有起到先入后出的作用
        while(!inStack.empty()){
            //将输入栈栈顶的元素弹出给输出栈
            outStack.push(inStack.top());
            inStack.pop();
        }
    }
public:
    CQueue() {

    }
    
    void appendTail(int value) {
        inStack.push(value);
    }
    
    int deleteHead() {
        if(outStack.empty()){
            if(inStack.empty()){
                //输入栈输出栈都为空,表明队列中没有元素
                return -1;
            }
            //输出栈没有元素但输入栈有,将输入栈全部元素压入输出栈
            in2out();
        }
        //输出栈弹出栈顶元素
        int value = outStack.top();
        outStack.pop();
        return value;

    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

  leetcode225.用队列实现栈

双队列:

双队列:一个队列用来模拟栈存放数据,另一个辅助队列用来备份数据。每次需要弹出元素的时候,把除了最后一个元素的所有元素弹出存入辅助队列中,等最后一个元素弹出后再把辅助队列的所有临时数据存到主队列中,辅助队列清零。

class MyStack {
private:
    queue<int> que1;
    queue<int> que2;//辅助队列
public:
    MyStack() {

    }
    
    void push(int x) {
        que1.push(x);
    }
    
    int pop() {
        int size = que1.size();
        --size;
        while(size -- ){
            que2.push(que1.front());
            que1.pop();//将que1除了队尾的元素,其他全部放入que2中
        }
        int res = que1.front();//队尾的元素,即栈的栈头
        que1.pop();
        que1 = que2;//将que2中的元素全部赋给que1
        while(!que2.empty()){
            que2.pop();//清空que2
        }
        return res;
    }
    
    int top() {
        return que1.back();
    }
    
    bool empty() {
        return que1.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

单队列

双队列有优化的空间,我们发现,一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。

class MyStack {
private:
    queue<int> q;
public:
    MyStack() {
        
    }
    
    void push(int x) {
        q.push(x);
    }
    
    int pop() {
        int size = q.size();
        -- size;
        while(size > 0){
            //将队列头部的元素(除了最后一个元素之外) 重新添加到队列尾部
            q.push(q.front());
            q.pop();
            -- size;
        }
        int res =  q.front(); //此时弹出的元素顺序就是栈的顺序了
        q.pop();
        return res;
    }
    
    int top() {
        return q.back();
    }
    
    bool empty() {
        return q.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */