刷题计划 day10 栈与队列上【用栈实现队列】【用队列实现栈】【有效的括号】【删除字符串中的所有相邻重复项】

⚡刷题计划day10栈与队列继续,可以点个免费的赞哦~

往期可看专栏,关注不迷路,

您的支持是我的最大动力🌹~

目录

⚡刷题计划day10继续,可以点个免费的赞哦~

往期可看专栏,关注不迷路,

您的支持是我的最大动力🌹~

题目一:232. 用栈实现队列

题目二:225. 用队列实现栈

法一:两个队列

法二:一个队列

题目三:20. 有效的括号

题目四:1047. 删除字符串中的所有相邻重复项

法一:使用ArrayDeque作为堆栈(效率一般)

法二:将字符串直接作为栈(效率较高)

法三:双指针(效率无敌高)


简单来说,栈是先进后出(FILO,First In Last Out),队列是先进先出(FIFO,First In First Out)的数据结构。

栈的常用操作

压栈(Push):将元素添加到栈顶。
弹栈(Pop):移除并返回栈顶元素。
查看栈顶元素(Peek):返回栈顶元素但不移除它。
检查栈是否为空(IsEmpty):判断栈是否没有任何元素。
获取栈的大小(Size):返回栈中元素的数量。

队列常用操作

入队(Offer):将元素添加到队列尾部。
出队(Poll):移除并返回队列头部的元素。
查看队首元素(Peek/Element):返回队列头部的元素但不移除它。
检查队列是否为空(IsEmpty):判断队列是否没有任何元素。
获取队列的大小(Size):返回队列中元素的数量。

题目一:232. 用栈实现队列

  1. 用栈实现队列

(https://leetcode.cn/problems/implement-queue-using-stacks/description/)

主要思路:

使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。

可以结合如下动画理解,这样就将栈转换为了队列:

注意几个点:

  • 在push时,直接将数据放进输入栈就可

  • 在pop时,会复杂一些,我们需要先判断输出栈是否为空,不为空直接输出;为空则需要将输入栈中的数据全部导入到输出栈,再弹出数据即可

  • 关于队列判空,如果进栈和出栈都为空的话,说明模拟的队列为空了。

代码如下:

import java.util.Stack;
​
class MyQueue {
​Stack<Integer> stackIn; // 负责进栈的栈Stack<Integer> stackOut; // 负责出栈的栈
​public MyQueue() {stackIn = new Stack<>(); // 初始化进栈栈stackOut = new Stack<>(); // 初始化出栈栈}
​public void push(int x) {stackIn.push(x); // 将元素x推入stackIn}public int pop() {dumpstackIn(); // 将stackIn中的元素转移到stackOut中return stackOut.pop(); // 弹出stackOut的栈顶元素}public int peek() {dumpstackIn(); // 将stackIn中的元素转移到stackOut中return stackOut.peek(); // 返回stackOut的栈顶元素但不移除}
​public boolean empty() {return stackIn.isEmpty() && stackOut.isEmpty(); // 如果两个栈都为空,则队列为空}
​//将功能相近的函数要抽象出来,就是将输入栈中的数据导入到输出栈private void dumpstackIn() {if (!stackOut.isEmpty()) return; // 如果stackOut不为空,则不需要转移while (!stackIn.isEmpty()) { // 当stackIn不为空时stackOut.push(stackIn.pop()); // 将stackIn的栈顶元素弹出并推入stackOut}}
}

题目二:225. 用队列实现栈

  1. 用队列实现栈

(https://leetcode.cn/problems/implement-stack-using-queues/description/)

这题开始也想着和上题一样,使用一个输入队列,一个输出队列,但是仔细想一下,行不通。

队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。

所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。

下面解法一先给出两个队列的实现

如下面动画所示,用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。

法一:两个队列

AC代码如下:

class MyStack {
​Queue<Integer> queue1; // 主队列,用来模拟栈Queue<Integer> queue2; // 辅助队列,用于临时存储元素
​/** * 初始化数据结构。*/public MyStack() {queue1 = new LinkedList<>(); // 初始化主队列queue2 = new LinkedList<>(); // 初始化辅助队列}/** * 将元素 x 压入栈顶。*/public void push(int x) {queue2.offer(x); // 先将元素 x 放入辅助队列while (!queue1.isEmpty()){ // 将主队列中的所有元素转移到辅助队列queue2.offer(queue1.poll());}Queue<Integer> queueTemp; // 临时变量用于交换队列queueTemp = queue1; // 交换队列,此时queue2成为主队列queue1 = queue2;queue2 = queueTemp;}/** * 移除并返回栈顶元素。*/public int pop() {return queue1.poll(); // 由于queue1模拟栈,所以直接移除并返回队首元素}/** * 获取栈顶元素。*/public int top() {return queue1.peek(); // 返回queue1的队首元素,即栈顶元素}/** * 判断栈是否为空。*/public boolean empty() {return queue1.isEmpty(); // 如果主队列为空,则栈为空}
}

法二:一个队列

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

AC代码

class MyStack {Queue<Integer> queue;
​public MyStack() {queue = new LinkedList<>();}
​public void push(int x) {queue.offer(x);int size = queue.size();while (size-->1)//将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部queue.offer(queue.poll());}
​public int pop() {return queue.poll();}
​public int top() {return queue.peek();}
​public boolean empty() {return queue.isEmpty();}
}

题目三:20. 有效的括号

  1. 有效的括号

(https://leetcode.cn/problems/valid-parentheses/description/)

由于栈结构的特殊性,非常适合做对称匹配类的题目。

分析:

第一种情况,字符串里左(右)方向的括号多余了 ,所以不匹配。

已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况,括号没有多余,但是 括号的类型没有匹配上。

遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况,字符串里右方向的括号多余了,所以不匹配。

遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!

根据以上分析三种情况实现,AC代码如下:

class Solution {public boolean isValid(String s) {if(s.length()%2 != 0){return false;}char[] c = s.toCharArray();Deque<Character> deque = new LinkedList<>();for (int i=0;i<s.length();i++){if(c[i] == '('){deque.push(')');}else if (c[i] == '{'){deque.push('}');}else if (c[i] == '['){deque.push(']');}else if(deque.isEmpty() || deque.peek()!=c[i]){return false;}else{deque.pop();}}return deque.isEmpty();}
}

题目四:1047. 删除字符串中的所有相邻重复项

  1. 删除字符串中的所有相邻重复项

(https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/)

本题要删除相邻相同元素,相对于[20. 有效的括号]来说其实也是匹配问题,[20. 有效的括号]是匹配左右括号,本题是匹配相邻元素,最后都是做消除的操作。

本题也是用栈来解决的经典题目。

法一:使用ArrayDeque作为堆栈(效率一般)

大致思路:

开始先将字符入栈,然后下一字符入栈前判断是否与已入栈字符相等。

若相等,则直接将栈中元素弹出,

若栈为空或不相等,则入栈,

将字符串遍历结束后,将栈中字符导出为字符串格式,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。

动画如图:

AC代码及注释:

class Solution {public String removeDuplicates(String s) {//1.ArrayDeque会比LinkedList在除了删除元素这一点外会快一点//2.在Java中,ArrayDeque 是双端队列的实现,它提供了队列和栈的功能。尽管它是一个队列,但它同时支持在两端进行操作,所以它也可以用来模拟栈的行为,直接调用对应方法即可。ArrayDeque<Character> queue = new ArrayDeque<>();char[] c = s.toCharArray();for(int i=0;i<s.length();i++){if(queue.isEmpty() || c[i] != queue.peek()){queue.push(c[i]);}else {queue.pop();}}String str = "";//注意这里挺妙,queue.pop() 作为第一个加数,这样我们就不需要再翻转字符串了。while (!queue.isEmpty()){str = queue.pop() +str;}return str;
​}
}

法二:将字符串直接作为栈(效率较高)

拿字符串直接作为栈,省去了栈还要转为字符串的操作,效率较高。

AC代码及注释:

class Solution {public String removeDuplicates(String s) {StringBuilder sb = new StringBuilder();for (char c : s.toCharArray()) {// 如果StringBuilder不为空,并且最后一个字符与当前字符相同if (sb.length() != 0 && sb.charAt(sb.length() - 1) == c) {// 删除StringBuilder中的最后一个字符sb.deleteCharAt(sb.length() - 1);} else {// 否则,将当前字符添加到StringBuilder中sb.append(c);}}return sb.toString();}
}

法三:双指针(效率无敌高)

AC代码及注释:

class Solution {public String removeDuplicates(String s) {char[] ch = s.toCharArray();int fast = 0;int slow = 0;while(fast < s.length()){// 直接用fast指针覆盖slow指针的值ch[slow] = ch[fast];// 遇到前后相同值的,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了if(slow > 0 && ch[slow] == ch[slow - 1]){slow--;}else{slow++;}fast++;}return new String(ch,0,slow);}
}

有所帮助可以点个免费的赞赞哦~🌹

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

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

相关文章

【中级通信工程师】终端与业务(三):电信业务

【零基础3天通关中级通信工程师】 终端与业务(三)&#xff1a;电信业务 本文是中级通信工程师考试《终端与业务》科目第三章《电信业务》的复习资料和真题汇总。终端与业务是通信考试里最简单的科目&#xff0c;有效复习通过率可达90%以上&#xff0c;本文结合了高频考点和近几…

数字化转型:开启未来发展新引擎

在当今飞速发展的时代&#xff0c;数字化转型已成为企业、组织乃至整个社会发展的关键趋势。 信息技术的迅猛发展&#xff0c;如互联网、大数据、人工智能等&#xff0c;为数字化转型提供了强大支撑。市场竞争的加剧&#xff0c;也促使企业不断寻求提升竞争力的方法&#xff0c…

【CSS/HTML】圣杯布局和双飞翼布局实现两侧宽度固定,中间宽度自适应及其他扩展实现

前沿简介 圣杯布局和双飞翼布局是前端重要的布局方式。两者的功能相同&#xff0c;都是为了实现一个两侧宽度固定&#xff0c;中间宽度自适应的三栏布局。 圣杯布局来源于文章In Search of the Holy Grail,双飞翼布局来源于淘宝UED。 两者的实现方式有差异&#xff0c;但是都…

黑马头条day4 自媒体文章自动审核

阿里云内容安全调用 其实这个接口调用不是很难 但是需要花钱 就没买 我开了按量计费 但是还是不行 所以就没测试 于是尝试自己写返回成功值 效果不好 后来发现不如直接在函数里边取消调用文字和图片审核 这样更简单 远程调用与降级处理 这里有个bug调试了好久 第一个就是总…

STL之vector篇(下)(手撕底层代码,从零实现vector的常用指令,深度剖析并优化其核心代码)

文章目录 1.基本结构与初始化1.1 空构造函数的实现与测试1.2 带大小和默认值的构造函数1.3 使用迭代器范围初始化的构造函数(建议先看完后面的reserve和push_back)1.4 拷贝构造函数1.5 赋值操作符的实现&#xff08;深拷贝&#xff09;1.6 析构函数1.7 begin 与 end 迭代器 2. …

使用 sponge + dtm 轻松实现秒杀抢购服务(HTTP),彻底解决库存与订单数据不一致的难题

秒杀场景的挑战 秒杀是电商中常见的抢购商品场景&#xff0c;其技术特点是瞬间请求量巨大&#xff0c;对服务的性能和一致性要求极高。即使服务出现崩溃&#xff0c;也必须确保库存扣减和订单生成保持一致&#xff0c;避免出现超卖或超买的现象。通过使用 dtm&#xff08;分布…

【重要提示】由于找不到msvcr110.dll 无法继续执行的解决途径全面解析

在使用Windows操作系统时&#xff0c;您可能会遇到这样的问题&#xff1a;某些应用程序在启动时提示“由于找不到 msvcr110.dll&#xff0c;无法继续执行代码。重新安装程序可能会解决此问题。” 这种错误通常会导致应用程序无法正常运行&#xff0c;影响用户体验。本文将全面介…

MySQL 预处理语句:强大的数据库工具

《MySQL 预处理语句&#xff1a;强大的数据库工具》 在 MySQL 数据库的使用中&#xff0c;预处理语句是一个非常有用的功能。它可以提高数据库的性能、安全性和可维护性。那么&#xff0c;什么是预处理语句呢&#xff1f;它又有哪些优点呢&#xff1f;让我们一起来了解一下。 …

docker - 镜像操作(拉取、查看、删除)

文章目录 1、docker search --help&#xff08;用于显示 Docker 搜索命令的帮助信息&#xff09;2、docker pull&#xff08;拉取镜像&#xff09;3、docker images (查看镜像)3.1、docker images --help&#xff08;用于显示 Docker 镜像管理相关命令的帮助信息&#xff09;3.…

【数据结构】排序算法---桶排序

文章目录 1. 定义2. 算法步骤3. 演示3.1 动态演示13.2 动态演示23.3 图片演示13.4 图片演示2 4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 1. 定义 桶排序&#xff08;英文&#xff1a;Bucket sort&#xff09;是计数排序的升级版&#xff0c;适用于待排序数据值域…

Elasticsearch黑窗口启动乱码问题解决方案

问题描述 elasticsearch启动后有乱码现象 解决方案&#xff1a; 提示&#xff1a;这里填写该问题的具体解决方案&#xff1a; 到 \config 文件下找到 jvm.options 文件 打开后 在文件末尾空白处 添加 -Dfile.encodingGBK 保存后重启即可。

1. Linux系统(CentOS7.9)安装

toc 一、Linux概述介绍 1、Linux系统介绍 Linux, 一类操作系统的统称 部署在服务器上&#xff0c;部署项目、应用 服务器: 硬件设备, 柜式服务器&#xff0c;(华为、浪潮、联想) 提供服务的机器 2、Linux的优势 开源, open source , 开放源代码稳定性最大化发挥硬件资源 …

微服务注册中⼼1

1. 微服务的注册中⼼ 注册中⼼可以说是微服务架构中的”通讯录“ &#xff0c;它记录了服务和服务地址的映射关系。在分布式架构中&#xff0c; 服务会注册到这⾥&#xff0c;当服务需要调⽤其它服务时&#xff0c;就这⾥找到服务的地址&#xff0c;进⾏调⽤。 1.1 注册中⼼的…

【Redis入门到精通七】详解Redis持久化机制(AOF,RDB)

目录 Redis持久化机制 1.RDB持久化 &#xff08;1&#xff09;手动触发RDB持久化 &#xff08;2&#xff09;自动触发RDB持久化 &#xff08;3&#xff09;Redis文件相关处理 &#xff08;4&#xff09;RDB持久化的优缺点 2.AOF持久化 &#xff08;1&#xff09;AOF工作…

【隐私计算篇】利用多方安全计算MPC实现VGG16人脸识别隐私推理

1. 背景介绍 本文主要介绍一种利用多方安全计算MPC技术&#xff0c;实现VGG16的人脸识别模型&#xff0c;侧重于模型推理阶段&#xff0c;目前已经公开专利&#xff0c;因此以下内容的分享都是基于公开材料。该分享涉及到最小化多方安全计算(MPC)以及明密文混合计算的思想&…

签署《AI安全国际对话威尼斯共识》 智源持续推动人工智能安全发展

近日&#xff0c;由AI安全国际论坛&#xff08;Safe AI Forum&#xff09;和博古睿研究院&#xff08;Berggruen Institute) 共同举办的第三届国际AI安全对话&#xff08;International Dialogues on AI Safety&#xff09;在威尼斯举办。图灵奖得主Yoshua Bengio、姚期智教授&…

UBUNTU20.04安装CH384串口卡驱动

继续上文&#xff1a;统信UOS安装CH384串口卡驱动-CSDN博客 统信UOS系统成功安装CH384串口驱动后&#xff0c;继续在ubuntu20.04下安装驱动&#xff0c;发现一直报错&#xff0c;原因是内核驱动不一致。 解决办法&#xff1a; 1. 下载最新的驱动。CH35XCH384驱动源文件资源-C…

Java语言程序设计基础篇_编程练习题**18.30 (找出单词)

题目&#xff1a;**18.30 (找出单词) 编写一个程序&#xff0c;递归地找出某个目录下的所有文件中某个单词出现的次数。从命令行如下传递参数&#xff1a; java Exercise18_30 dirName word 习题思路 &#xff08;读取路径方法&#xff09;和18.28题差不多&#xff0c;把找…

Structure-Aware Transformer for Graph Representation Learning

Structure-Aware Transformer for Graph Representation Learning&#xff08;ICML22&#xff09; 摘要 Transformer 架构最近在图表示学习中受到越来越多的关注&#xff0c;因为它通过避免严格的结构归纳偏差而仅通过位置编码对图结构进行编码&#xff0c;自然地克服了图神经…

分享课程:VUE数据可视化教程

在当今这个数据驱动的世界中&#xff0c;数据可视化已经成为了一种至关重要的工具&#xff0c;它帮助我们理解复杂的数据集&#xff0c;发现模式、趋势和异常。数据可视化不仅仅是将数字转换成图表&#xff0c;它是一种将数据转化为洞察力的艺术。 1.什么是数据可视化&#xf…