代码随想录算法训练营第十天|232.用栈实现队列、225. 用队列实现栈

做今天题目之前,可以先了解一下栈与队列理论基础

文章链接:代码随想录代码随想录PDF,代码随想录百度网盘,代码随想录知识星球,代码随想录八股文PDF,代码随想录刷题路线,代码随想录知识星球八股文https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

栈是先进后出,队列是先进先出 

题目链接: 232.用栈实现队列

题目:

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。

思路: 第一次接触到题没啥思路,先看卡老师视频

视频链接:栈的基本操作! | LeetCode:232.用栈实现队列_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!代码随想录刷题网站:programmercarl.com, 视频播放量 27292、弹幕量 297、点赞数 597、投硬币枚数 413、收藏人数 130、转发人数 34, 视频作者 代码随想录, 作者简介 我是Carl,哈工大师兄,先后在腾讯和百度从事一线技术研发的程序员,公众号「代码随想录」,相关视频:Leetcode力扣 1-300题视频讲解合集|手画图解版+代码【持续更新ing】,2024王道408数据结构自制版(重点讲解+课后习题超详细讲解),计算机硕士我劝你别考,计算机学习最强技能树 照着这个路线不再迷茫,顺序栈的实现----C语言版,一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解,【喵的算法课】栈与队列 表达式计算【4期】,栈和队列练习题讲解,最浅显易懂的 KMP 算法讲解,栈的概念和基本操作https://www.bilibili.com/video/BV1nY4y1w7VC

可以通过设置两个栈来实现队列,一个进栈一个出栈,将进栈的所有元素同时移动到出栈就能实现队列的先进先出了,注意⚠️:必须是所有元素同时移动到出栈,如果部分移动,出栈元素的顺序会乱掉!

代码如下:

class MyQueue {
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;
    public MyQueue() {
        stackIn=new Stack<>(); //负责进栈
        stackOut=new Stack<>(); //负责出栈
    }
    
    //把元素 x 推到队列的末尾
    public void push(int x) {
        stackIn.push(x);
    }
    
    //移除队列开头元素并返回该元素,函数体里面调用的方法都是栈里面包含的,最后实现的功能是队列里的方法
    public int pop() {
        dumpstackIn();
        return stackOut.pop();
    }
    
    //返回队列开头的元素
    public int peek() {
        dumpstackIn();  
        return stackOut.peek(); //栈里面也有返回栈顶元素的peek函数,直接用就行
    }
    
    //判断是否为空
    public boolean empty() {
        return stackIn.isEmpty()&&stackOut.isEmpty();
    }

    //如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
    private void dumpstackIn(){
        // 必须得out里面没有元素了才能导进去,如果有元素就提前用pop方法将元素都弹出去,因为要优先使用out内的元素,如果out不为空就导进去了,元素出去的顺序就乱了
        if(!stackOut.isEmpty()) return;
        //循环里的条件不能写成是是否判断出栈为空,因为执行循环的时候,先把入栈里的一个元素pop出来再push进出栈,那么此时出栈就不为空了,入栈剩下的元素就不会再执行循环了
        while(!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
        }
    }
}

/**
 * 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();
 * boolean param_4 = obj.empty();
 */
  • 时间复杂度: push和empty为O(1), pop和peek为O(n)
  • 空间复杂度: O(n)

题目链接:225. 用队列实现栈

题目:

使用队列实现栈的下列操作:

push(x) -- 元素 x 入栈

pop() -- 移除栈顶元素

top() -- 获取栈顶元素

empty() -- 返回栈是否为空

卡老师视频链接:队列的基本操作! | LeetCode:225. 用队列实现栈_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!代码随想录刷题网站:programmercarl.com, 视频播放量 19564、弹幕量 225、点赞数 433、投硬币枚数 267、收藏人数 83、转发人数 24, 视频作者 代码随想录, 作者简介 我是Carl,哈工大师兄,先后在腾讯和百度从事一线技术研发的程序员,公众号「代码随想录」,相关视频:优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素,栈的基本操作! | LeetCode:232.用栈实现队列,拿下滑动窗口! | LeetCode 209 长度最小的子数组,梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!,单调队列正式登场!| LeetCode:239. 滑动窗口最大值,贪心算法理论基础!,栈的拿手好戏!| LeetCode:20. 有效的括号,学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集,拿不准的遍历顺序,搞不清的回溯过程,我太难了! | LeetCode:112. 路径总和,帮你把KMP算法学个通透!(理论篇)https://www.bilibili.com/video/BV1Fd4y1K7sm

思路: 

刚刚做过栈与队列:我用栈来实现队列怎么样? (opens new window)的同学可能依然想着用一个输入队列,一个输出队列,就可以模拟栈的功能,仔细想一下还真不行!队列模拟栈,其实一个队列就够了,那么我们先说一说两个队列来实现栈的思路。

队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。这和通过1个队列的做题思路基本一致,1个队列只不过是把除了最后面的元素之外的其余元素重新导入到这个队列中去。

用1个队列做题代码如下:

class MyStack {
    Queue<Integer> queue;
    public MyStack() {
        queue=new LinkedList<>();
    }
    
    public void push(int x) {
        queue.add(x);
    }
    
    public int pop() {
        rePosition();
        return queue.poll(); //poll()方法是Queue接口中定义的一个方法,它用于从队列的头部删除并返回一个元素
    }
    
    public int top() {
        rePosition();
        int result=queue.poll(); //此时queue就剩下最后一个元素了,因为队列里面没有栈里面返回栈顶元素的peek函数,所以为了得到这个元素需要间接通过poll方法,poll()方法它用于从队列的头部删除并返回一个元素
        queue.add(result); //再把刚刚通过poll删除的元素重新添加进去
        return result; //返回那个元素
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }

    public void rePosition(){
        int size=queue.size();
        size--; //将除了尾元素以外的其它元素全部重新导入到这个队列中去
        while(size-->0){
            queue.add(queue.poll()); //poll()方法是Queue接口中定义的一个方法,它用于从队列的头部删除并返回一个元素
        }
    }
}

/**
 * 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();
 * boolean param_4 = obj.empty();
 */
  • 时间复杂度: push为O(n),其他为O(1)
  • 空间复杂度: O(n)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan_lwh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值