【代码随想录Day 2 - 栈和队列 ① 1~3】

Carl 语录

把常用的函数抽象出来,形成自己的工具库。而不要每次都cv修修改改。

可以看出peek()的实现,直接复用了pop(), 要不然,对stOut判空的逻辑又要重写一遍。
1.问题:再多说一些代码开发上的习惯问题,在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。 这样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!(踩过坑的人自然懂)
2.建议:工作中如果发现某一个功能自己要经常用,同事们可能也会用到,自己就花点时间把这个功能抽象成一个好用的函数或者工具类,不仅自己方便,也方便了同事们。
3.益处:同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!

2. 用栈实现队列

一刷无思路
232. 用栈实现队列

实现目标:

先入后出 =》先入先出

思路:

  • 先入后出 即 取出顺序与放入顺序相反,故两次 “先入后出” 之后,可实现“先入先出”。即将元素放入栈后,再将元素放入第二个栈内,此时从后者中取出元素,即从整体上看遵循“先入先出”。

实现过程:

  1. 一个输入栈stIn;push() 将队列元素放入此栈。由于栈是先入后出的,故先放入的元素在栈底

  2. 一个输出栈stOut:pop() 若栈为空,则将 stIn 中元素全部取入stOut,由于栈是先入后出的,故此时先放入的元素在栈顶

代码

class MyQueue {
public:
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {

    }
    
    void push(int x) {
        stIn.push(x); 
    }
    
    int pop() {
        if(stOut.empty()){
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
            int  result = stOut.top();  // 取出后删除此元素。但栈的pop()并不返回元素,需要提前用变量存储
            stOut.pop();
            return result;    
    }
    
    int peek() {
        if(stOut.empty()){   //判空。若输出栈不为空则从stOut顶部取元素;若为空,则需要从stIn中取至栈底元素。
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        return stOut.top();

        // int result = this->pop(); // 该数据结构没有 直接取顶部top而不删去top 的函数。复用方法有利于软件工程化
        // stOut.push(result);
    }
    
    bool empty() {
        return stOut.empty() && stIn.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();
 */

3. 用队列实现栈

225. 用队列实现栈

实现目标

先入先出=》后入先出:每次取出的都是当前最后放入的元素。

思路

  • 用一个队列实现栈: 那么每次取出时,将所有元素放置于最后一个元素的后面即可。
  • 用两个队列实现栈: 那么每次取出时,将一个队列中除最后一个元素外全部放入另一个队列中,再取出前者中的元素即可。

实现过程

  • Carl 的实现是只将所有元素放在que1,每次 “出栈” ——
    1)将que1中除队尾元素外全部转入que2中;
    2)取出 que1 队尾元素;
    3)再从que2倒回que1,每次 “出栈” 要转移两次

  • 我认为这个过程比较耗时,故加入判定,
    1)哪个不为空就从那个队列倒入另一个队列;
    2)取出 该队列 队尾元素,每次 “出栈” 只转移一次

代码

Carl 《代码随想录》的分析过程及代码

  • 用两个队列实现栈:(元素在两个队列之间来回倒)
class MyStack {
public:
//元素在两个队列来回倒
    queue<int> que1;
    queue<int> que2;

    MyStack() {

    }
    
    void push(int x) { 
        if(que1.empty()) que2.push(x); //que1为空则说明元素都在que2中
        else que1.push(x);
    }
    
    int pop() {
         // 如果栈为空,则返回null
        if(this->empty()) return -1; 

        //如果que1为空,则说明元素都在que2
        if(que1.empty()){
            // 当que2有多个元素时,将除队列尾部外的所有元素转移到que1
            while(que2.size() > 1){
                que1.push(que2.front());
                que2.pop();
            }

            //当que2中只有1个元素时,返回该元素,并从que2中删除
            int result = que2.front();
            que2.pop();
            return result;            
        }

        //如果que1不为空,则说明元素都在que1
        //当que1有多个元素时,将除队列尾部外的所有元素转移到que2
        while(que1.size() > 1){
            que2.push(que1.front());
            que1.pop();
        }
        //当que1中只有1个元素时,返回该元素,并从que1中删除
        int result = que1.front();
        que1.pop();
        return result;
    }
    
    int top() {
        //复用函数
        int result = this->pop(); // 保存栈顶元素
        this->push(result); //重新放回
        return result;

    }
    
    bool empty() {
        return (que1.empty() && que2.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();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值