第二周第五天|力扣232、用栈实现队列 225、用队列实现栈

232、用栈实现队列

思路:这道题目考察的是对栈和队列的理解,栈是先进后出,队列是先进先出,根据这个特性,要想用栈来模拟队列,一个栈是不够的,需要两个栈。

第一个栈的作用很明显,可以用来模拟入队,第二个栈就是用来模拟出队的关键了,要想让栈实现先进先出,就得将先进后出的结果再倒回来,因此第二个栈需要将第一个栈的全部,注意是全部数据依次弹出并压入第二个栈,为了方便说明,后面称第一个栈为入栈,第二个栈为出栈,此后只需要将出栈的元素依次弹出即可模拟队列的出队了。

接下来是实现取队首的操作,也就是peek,这里我们可以发现,它实现的关键和出队一样,也是对先进先出数据结构特性的使用,因此完全可以复用出队的函数,去获取队首元素的值,只不过在获取到元素的值之后,要把这个弹出的元素再压回出栈中。判断队空,就是判断两个栈是否全空,全空返回true,否则返回false。

总结:重点是理解出队的模拟,以及复用的魅力。

代码:

class MyQueue {
public:
    MyQueue() {

    }
    stack<int>stIn;
    stack<int>stOut;
    void push(int x) {//模拟入队
        stIn.push(x);
    }
    
    int pop() {//KEY:模拟出队
        if(stOut.empty()){
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result=stOut.top();
        stOut.pop();
        return result;
    }
    
    //注意复用
    int peek() {
        int res=this->pop();
        stOut.push(res);
        return res;
    }
    
    bool empty() {
        return stIn.empty()&&stOut.empty();
    }
};

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

225、用队列实现栈

思路:这道题目一开始有点惯性思维是正常的,就是认为既然可以用两个栈模拟队列,那我接着用两个队列来模拟栈就好了,这么做当然可以,但是可以更省事一些,只用一个队列就可以实现栈了。

入栈的操作最为简单,直接入队即可。出栈的操作是关键,在这里我们稍作思考,栈所弹出的元素是最后进入的元素,如果我能够在代码中让队列弹出最后一个元素,那么不就相当于实现了出栈的操作吗?因此,我可以把最后入队的元素之前的元素通通弹出并依次再插回队列里面,这样队首自然就是最后一个插入的元素了,弹出来就可以了。获取队首,这个地方不用复用代码了,既然队尾就是栈首,那么直接return队尾就好了,判空也是非常的方便,直接return队列的empty即可。

总结:可以看出,队列模拟栈要更加方便一些,不过虽然如此,不过我琢磨了一下,这样做的话,出栈的时间复杂度会达到O(n),也就是说实际上还是比真正的栈要慢的,只不过感觉上是模拟出了一个栈,因此本题主要的目的是为了加深对栈和队列的理解,实际还是直接用就好了。

代码:

class MyStack {
public:
    queue<int> que1;
    queue<int> que2; // 辅助队列,用来备份
   
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
         cout<<&que1<<endl;
        que1.push(x);
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
         
        int size = que1.size();
        size--;
        while (size--) { // 将que1 导入que2,但要留下最后一个元素
            que2.push(que1.front());
            que1.pop();
        }

        int result = que1.front(); // 留下的最后一个元素就是要返回的值
        que1.pop();
        cout<<&que1<<endl;
        que1 = que2;            // 再将que2赋值给que1
         cout<<&que1<<endl;
        while (!que2.empty()) { // 清空que2
            que2.pop();
        }
        return result;
    }

    /** Get the top element. */
    int top() {
        return que1.back();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return que1.empty();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值