两个栈实现队列和两个队列实现栈

一、两个栈实现队列

Leetcode 剑指offer 09

自己写的一个垃圾版本

主要想法就是,用st1用来进行push操作,如果说要pop的话,就把元素导到st2中,然后返回st2的栈顶元素,并且pop一下,然后将st2中元素再倒回st1中(这里又倒回去比较耗时)。

代码

class CQueue {
public:
    CQueue() {

    }
    void appendTail(int value) {
        st1.push(value);
    }
    int deleteHead() {
        while(!st1.empty())
        {
            st2.push(st1.top());
            st1.pop();
        }
        int tmp = -1;
        if(!st2.empty())
        {
            tmp = st2.top();
            st2.pop();
        }
        while(!st2.empty())
        {
            st1.push(st2.top());
            st2.pop();
        }
        return tmp;
    }
private:
    stack<int> st1;
    stack<int> st2;
};

官方的最优代码

主要的区别是利用st1完成push操作,然后st2完成pop操作,如果st2不是空的话就直接从st2 pop即可,就免除了st2->st1这部分的元素导入。
代码

class CQueue {
    stack<int> stack1,stack2;
public:
    CQueue() {
        while (!stack1.empty()) {
            stack1.pop();
        }
        while (!stack2.empty()) {
            stack2.pop();
        }
    }
    
    void appendTail(int value) {
        stack1.push(value);
    }
    
    int deleteHead() {
        // 如果第二个栈为空
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.top());
                stack1.pop();
            }
        } 
        if (stack2.empty()) {
            return -1;
        } else {
            int deleteItem = stack2.top();
            stack2.pop();
            return deleteItem;
        }
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/solution/mian-shi-ti-09-yong-liang-ge-zhan-shi-xian-dui-l-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、队列实现栈

(1)两个队列实现栈

利用两个队列q1和q2,每时每刻总有一个队列是空的用于导数据,如果要push就往非空的队列中push,如果要pop就将有数据的队列除了最后一个元素(就是要pop的栈顶)全部导到另一个队列中,然后把剩下的最后一个元素pop掉。top操作比较简单,直接返回有元素的那个数组的尾元素就好了。empty函数就不说了。

class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {

    }
    /** Push element x onto stack. */
    void push(int x) {
        if(q1.empty())
        {
            q2.push(x);
        }
        else{
            q1.push(x);
        }
    }
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        if(q1.empty()&&q2.empty()) return -1;
        int tmp = 0;
        if(q1.empty())
        {
            while(q2.size()>1)
            {
                q1.push(q2.front());
                q2.pop();
            }
            tmp = q2.front();
            q2.pop();
        }else{
            while(q1.size()>1)
            {
                q2.push(q1.front());
                q1.pop();
                
            }
            tmp = q1.front();
            q1.pop();
        }
        return tmp;
    }
    /** Get the top element. */
    int top() {
        if(q1.empty()&&q2.empty()) return -1;
        if(q1.empty())
        {
            return q2.back();
        }
        return q1.back();
    }
    /** Returns whether the stack is empty. */
    bool empty() {
        return q1.empty()&&q2.empty();
    }
private:
    queue<int> q1;
    queue<int> q2;
};

(2)一个队列实现栈

事实上由于队列一端可以pop另一端可以push,可以通过一个队列就实现栈。push操作还是一样,pop操作就需要记录当前队列的大小,将队首的元素pop出来插入队尾,当之前队尾元素(栈顶元素)到达队首时就可以进行栈的pop操作了。

class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {

    }
    /** Push element x onto stack. */
    void push(int x) {
        q.push(x);
    }
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        if(q.empty()) return -1;
        int size = q.size();
        while(--size)
        {
            q.push(q.front());
            q.pop();
        }
        int tmp = q.front();
        q.pop();
        return tmp;
    }
    /** Get the top element. */
    int top() {
        if(q.empty()) return -1;
        return q.back();
    }
    /** Returns whether the stack is empty. */
    bool empty() {
        return q.empty();
    }
private:
    queue<int> q;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值