代码随想录算法训练营第 10天 | 题目:232.用栈实现队列、225. 用队列实现栈 、20. 有效的括号、1047. 删除字符串中的所有相邻重复项

代码随想录算法训练营第 10天 | 题目:232.用栈实现队列、225. 用队列实现栈 、20. 有效的括号、1047. 删除字符串中的所有相邻重复项

文章来源:代码随想录

题目名称:232.用栈实现队列

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

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

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:
你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

第一想法:

栈是一头进出,队列是两头进出所以要使用两个栈来实现。

解答思路:

使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。
输出时由输出栈中输出,输出栈若空,则将输入栈都压入输出栈中,经过这个流程实现先进先出。

困难:

java栈的相关代码不熟悉,需要重新学习一下

收获:

理解栈的进出和队列的进出方式。

题目名称:225. 用队列实现栈

使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

第一想法:

是否和上一题一样,一个控制入一个控制出。但模拟后无法达到目的。是否可以在出的时候将最后一位之前的所有数值存放于q2中再pop最后一位,然后交换q1、q2即可。

解答思路:

队列模拟栈,其实一个队列就够了,那么我们先说一说两个队列来实现栈的思路。

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

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

但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!

如下面动画所示,用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。
是要更改push的问题,q1的序列完全按照栈的出序列顺序,也就是将压入的值放在q1的最里端。

收获:

首先是java队列的构建代码,ArrayDeque和 LinkedList实现队列。其次模拟栈的数据原理。

ArrayDeque是 Deque接口的一个实现,使用了可变数组,所以没有容量上的限制。同时,
ArrayDeque是线程不安全的,在没有外部同步的情况下,不能再多线程环境下使用。 ArrayDeque是
Deque的实现类,可以作为栈来使用,效率高于 Stack;也可以作为队列来使用,效率高于 LinkedList。 ArrayDeque 是
Java 集合中双端队列的数组实现,双端队列的链表实现(LinkedList) 需要注意的是, ArrayDeque不支持 null值。
原文链接:https://blog.csdn.net/mingyuli/article/details/115830113

题目名称:20. 有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:

输入: “()”
输出: true
示例 2:

输入: “()[]{}”
输出: true
示例 3:

输入: “(]”
输出: false
示例 4:

输入: “([)]”
输出: false
示例 5:

输入: “{[]}”
输出: true

第一想法:

使用栈解决,是否是将所有括号压入后再处理,或是使用三个不同类的栈分别,左括号则压入,右括号弹出,是否最后的栈是空栈

解答思路:

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。
先来分析一下 这里有三种不匹配的情况,
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 在这里插入图片描述

第二种情况,括号没有多余,但是 括号的类型没有匹配上。
在这里插入图片描述

第三种情况,字符串里右方向的括号多余了,所以不匹配。 括号匹配3
在这里插入图片描述

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!

困难:

想到右括号入栈的表示

收获:

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

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

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:“abbaca”
输出:“ca”
解释:例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
提示:

1 <= S.length <= 20000
S 仅由小写英文字母组成。

第一想法:

当与栈顶不同时压入,当相同则弹出栈顶。最后弹出栈,顺序需要反转。

解答思路:

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?
所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

收获:

栈适用于匹配问题

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值