算法打卡day9|栈与队列篇01|Leetcode 232.用栈实现队列、225. 用队列实现栈

栈与队列理论基础

栈(Stack)


栈是一种后进先出(LIFO)的数据结构,即最近添加到栈中的元素将是第一个被移除的元素。

栈通常有两个主要的操作:push 用于添加一个元素到栈顶,而 pop 用于移除栈顶的元素。此外,还有一个 peek 操作,它允许查看栈顶元素而不移除它。

在Java中,Stack 类是一个继承自 Vector 的类,提供了栈的实现。但是,由于 Vector 是同步的,这可能导致不必要的性能开销,因此在单线程应用程序中,更推荐使用 ArrayDeque 类,它实现了 Deque 接口并提供了一个更高效的栈实现

队列(Queue)


队列是一种先进先出(FIFO)的数据结构,即最先添加到队列中的元素将是第一个被移除的元素。

队列的基本操作包括 enqueue(添加元素到队列尾部)和 dequeue(移除队列头部的元素)。与栈类似,还有一个 peek 操作,用于查看队列头部的元素而不移除它。

Java中,LinkedList 类可以作为队列使用,因为它实现了 List 接口,而 List 接口又扩展了 Queue 接口。但是,LinkedList 不是专门为队列操作优化的。对于需要高性能队列的场景,可以使用 ArrayDeque ,它同样实现了 Deque 接口,并且提供了队列的高效实现

栈与队列的使用场景

  • :适用于需要后进先出特性的场合,例如函数调用栈(每次调用新函数时将其推入栈,返回时弹出栈),表达式求值(如后缀表达式的计算),以及深度优先搜索(DFS)等。
  • 队列:适用于需要先进先出特性的场合,例如任务调度(按顺序处理任务),广度优先搜索(BFS),以及实现生产者-消费者问题等。

栈和队列的物理与逻辑存储结构


物理存储结构指的是数据在计算机内存中实际的存储方式,而逻辑存储结构描述的是数据元素之间的抽象关系。

  • 数组是一种顺序存储结构,数据在内存中连续存放。
  • 链表是一种链式存储结构,数据在内存中可能分散存放,每个元素通过指针连接。

栈和队列都可以通过数组和链表来实现,具体选择哪种物理存储结构取决于具体的应用场景和性能需求。例如,对于栈,如果我们知道栈的大小不会变化太多,可以使用数组实现;如果栈大小经常变化,使用链表可能更加合适。对于队列,如果队列操作频繁,且队列大小固定,可以使用循环数组实现;如果队列大小可变,使用链表实现可能更加高效。

算法题

Leetcode  232.用栈实现队列

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

大佬视频讲解:用栈实现队列视频讲解

个人思路

需要两个栈一个输入栈,一个输出栈;push数据的时候,数据直接放进输入栈就好;但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。

解法
class MyQueue {Stack<Integer> stackIn;//输入栈Stack<Integer> stackOut;//输出栈public MyQueue() {stackIn = new Stack<>(); // 负责进栈stackOut = new Stack<>(); // 负责出栈}public void push(int x) {//插入数据stackIn.push(x);}public int pop() { //弹出数据   dumpstackIn();//1.先将输入栈全部弹出到输出栈return stackOut.pop();//2.再弹出输出栈数据}public int peek() {//获取一个输入的数据dumpstackIn();//1.先将输入栈全部弹出到输出栈return stackOut.peek();//2.输出栈的第一个数据 就是队列的第一个数据}public boolean empty() {//判空return stackIn.isEmpty() && stackOut.isEmpty();}// 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中private void dumpstackIn(){    if (!stackOut.isEmpty()) return; while (!stackIn.isEmpty()){stackOut.push(stackIn.pop());//将输入栈全部弹出到输出栈}}
}
 

时间复杂度:O(n);(push和empty为O(1), pop和peek为O(n)

空间复杂度:O(n);(2个辅助栈)

Leetcode 225. 用队列实现栈

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

大佬视频讲解:225. 用队列实现栈

个人思路

也是需要用两个队列que1和que2实现栈的功能其中que2其实完全就是一个数据备份的作用.在实现栈的push功能时,先将push 的元素放进que2,再看que1中有没有其他元素,有就把元素输出放入que2,再将que2变成que1, 这样que1弹出元素的顺序和原来栈完全一样了;

举个例子

队列1中现在有一个元素1, 需要放入4, 先将4放入队列2备份,再将1弹出放入队列2,这样队列2就变成了1,4 再将队列2和队列1交换,这样队列1的顺序就和栈的顺序一样了; 这样后续实现栈的弹出就直接弹出即可

解法

class MyStack {Queue<Integer> queue1; // 和栈中保持一样元素的队列Queue<Integer> queue2; // 备份队列public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}public void push(int x) {queue2.offer(x); // 先放在备份队列中while (!queue1.isEmpty()){queue2.offer(queue1.poll());//将队列1的元素全部弹出放入队列2}Queue<Integer> queueTemp;queueTemp = queue1;queue1 = queue2;queue2 = queueTemp; // 最后交换队列1和队列2,将元素都放到队列1中}public int pop() {return queue1.poll(); // 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可}public int top() {return queue1.peek();}public boolean empty() {return queue1.isEmpty();}
}

时间复杂度:O(n);(pop为O(n),其他为O(1))

空间复杂度:O(n);(两个队列)

还可以优化到一个队列实现

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了

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();}public int top() {rePosition();int result = queue.poll();queue.add(result);return result;}public boolean empty() {return queue.isEmpty();}public void rePosition(){//将队头元素移到队尾 除了最后一个元素int size = queue.size();size--;while(size-->0)queue.add(queue.poll());}
}

时间复杂度:O(n);(top,pop为O(n),其他为O(1))

空间复杂度:O(n);(两个队列)

以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网代码随想录算法官网代码随想录算法官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726833.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维码样式修改如何在线处理?在电脑上改二维码图案的方法

随着网络的不断发展&#xff0c;二维码的应用场景不断增多&#xff0c;很多人都会将内容放到二维码中&#xff0c;通过扫码的方式将储存在云端的数据调取显示。而面对不同的用途时&#xff0c;对二维码的样式也会有单独的要求&#xff0c;比如需要改变颜色、加入文字、logo、尺…

网络调试助手使用MQTT协议与Mosquitto通信(3)

一、连接报文 一开始设备需要连接到mqtt服务器&#xff0c;连接时的数据包内需要携带对应的设备ID&#xff0c;以及用户名和密码。这使用默认的用户名和密码。设备ID每一个设备都需要设置为不同的&#xff0c;两个相同的ID只能允许一台设备在线&#xff0c;另一个相同的ID的设备…

【C++庖丁解牛】模版初阶

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1. 泛型编程2. 函数模…

Dgraph 入门教程二《 快速开始》

1、Clound 云 云地址&#xff1a;Dgraph Cloud 登录Clound 云后&#xff0c;可以用云上的东西操作&#xff0c;可以用谷歌账号或者github账号登录。 启动云 &#xff08;1&#xff09;在云控制台&#xff0c;点击 Launch new backend. &#xff08;2&#xff09;选择计划&…

【PowerMockito:编写单元测试过程中原方法使用@Value注解注入的属性出现空指针】

错误场景 执行到Value的属性时会出现空指针&#xff0c;因为Value的属性为null 解决方法 在测试类调用被测试方法前&#xff0c;提前设置属性值&#xff0c;属性可以先自己定义好 ReflectionTestUtils.setField(endpointConnectionService, "exportUdpList", lis…

工业深度学习异常缺陷检测实战

在工业生产过程中&#xff0c;由于现有技术、工作条件等因素的不足和局限性&#xff0c;极易影响制成品的质量。其中&#xff0c;表面缺陷是产品质量受到影响的最直观表现&#xff0c;因此&#xff0c;为了保证合格率和可靠的质量&#xff0c;必须进行产品表面缺陷检测。 “缺陷…

制片管理工具:提高制片效率的必备工具

一、什么是制片管理工具 制片管理工具是一种为制片人提供支持和协助的软件或工具&#xff0c;并提供一种集中管理制作进度、任务分配、成本预算、资源管理和进度跟踪的方式。它可以帮助制片人在项目的开发、制作和发布方面更有效地进行规划和监督&#xff0c;确保整个流程能够…

LLM | Gemma的初体验

一起来体验一下吧~ 技术报告书&#xff1a;jgoogle/gemma-7b-it Hugging Facegemma-report.pdf (storage.googleapis.com) 代码1 &#xff1a;google-deepmind/gemma: Open weights LLM from Google DeepMind. (github.com) 代码2 &#xff1a;https://github.com/google/gem…

报名开启丨掘金海外,探寻泛娱乐社交APP出海新风口

随着国内泛娱乐行业用户规模趋于见顶&#xff0c;泛娱乐社交APP转向出海是必然趋势。 根据行业数据显示&#xff0c;有超过35%的国内实时社交企业已启动或者正在规划出海&#xff0c;而其中出海商户的音视频流量增长均超过了100&#xff05;。尤其是在东南亚、中东、拉美等新兴…

Maya笔记 软选择

文章目录 1什么是软选择2注意3如何打开软选择3.1方法一3.2方法二 4调整软选择的范围5衰减模式5.1体积模式5.2表面模式 6衰减曲线 1什么是软选择 也就是渐变选择&#xff0c;从中心点向外影响力度越来越小 软选择针对的是点线面这些模型元素 下图中展示了对被软选择的区域移动…

Rust入门:Rust如何调用C静态库的函数

关于Rust调用C&#xff0c;因为接口比较复杂&#xff0c;貌似Rust不打算支持。而对于C函数&#xff0c;则相对支持较好。 如果要研究C/Rust相互关系的话&#xff0c;可以参考&#xff1a; https://docs.rs/cxx/latest/cxx/ Rust ❤️ C 这里只对调用C静态库做一个最简短的介…

干货教程【软件篇】如何在Windows上安装Python环境以及设置国内源(Miniconda/Anaconda安装)

本文章涉及的所有安装包均在文章下方公众号中&#xff0c;回复python即可获取资源。 也可关注我们的官方网站&#xff1a; 考拉AI 小白安装前须了解一下 Python解释器是用来解释运行我们编写的Python代码。 Python标准库是Python自带的一系列标准模块&#xff0c;提供了各种…

浏览器修改接口返回数据展示在页面上

前端自己调试&#xff0c;想修改接口返回来的数据&#xff0c;然后展示在页面上 举例 接口返回了数据&#xff0c;想要修改此数据 这时就可以修改数据了&#xff0c;修改完成保存 然后刷新页面就会使用本地保存的数据了

Linux编程3.4 进程-进程标识

1、相关函数 #include<unistd.h> #include<sys/types.h> pid_t getpid(void); 获得当前进程ID uid_t getuid(void); 获得当前进程的实际用户ID uit_t geteuid(void); 获得当前进程的有效用户ID git_t getgid(void); 获得当前进程的用户组ID pit_t getppid(…

信号处理--基于单通道脑电信号EEG的睡眠分期评估

背景 睡眠对人体健康很重要。监测人体的睡眠分期对于人体健康和医疗具有重要意义。 亮点 架构在第一层使用两个具有不同滤波器大小的 CNN 和双向 LSTM。 CNN 可以被训练来学习滤波器&#xff0c;以从原始单通道 EEG 中提取时不变特征&#xff0c;而双向 LSTM 可以被训练来将…

数据库-DDL

show databases; 查询所有数据库 select database(); 查询当前数据库 use 数据库名&#xff1b; 使用数据库 creat database[if not exists] 数据库名…

vue2中如何实现添加一个空标签的效果,</>

前言&#xff1a; 众所周知&#xff0c;vue3突破了每一个vue文件中只能有一个根标签的限制&#xff0c;但是我们还有很多项目都是vue2的项目&#xff0c;如果让vue2中实现一个类似</>的效果呢&#xff0c;像react的16.2.0的版本之后&#xff0c;可以直接用<></&…

2024 年 AI 辅助研发趋势

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…

【动态规划】【数论】【区间合并】3041. 修改数组后最大化数组中的连续元素数目

作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 数论 区间合并 LeetCode3041. 修改数组后最大化数组中的连续元素数目 给你一个下标从 0 开始只包含 正 整数的数组 nums 。 一开始&#xff0c;你可以将数组中 任意数量 元素增加 至多 1 。 修改后&#xff0c;你可以从…

Spring Boot 3核心技术与最佳实践

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 highlight: a11y-dark 引言 Spring Boot作为…