首页 > 编程语言 >代码随想录算法训练营第十天 | 232.用栈实现队列 , 225. 用队列实现栈 , 20. 有效的括号 , 1047. 删除字符串中的所有相邻重复项

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

时间:2024-07-27 22:27:41浏览次数:12  
标签:遍历 匹配 第十天 队列 随想录 括号 slow return stack

前两道题目之前单独写了文章,此处就不再重复。

232.用栈实现队列-CSDN博客

225. 用队列实现栈-CSDN博客

20. 有效的括号

思路

括号匹配是使用栈解决的经典问题。

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

首先要弄清楚,字符串里的括号不匹配有几种情况。

一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。

先来分析一下 这里有三种不匹配的情况,

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

    括号匹配1

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

    括号匹配2

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

    括号匹配3

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

动画如下:

20.有效括号

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

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

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

那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。

分析完之后,代码其实就比较好写了,

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

方法一: 仅使用栈,更省空间

class Solution:
    def isValid(self,s:str) -> bool:
        if not str:
            return False
        record = []
        for char in s:
            if char == "[":
                record.append("]")
            elif char == "{":
                record.append("}")
            elif char == "(":
                record.append(")")
            elif record == [] or record[-1] != char:
                return False
            else:
                record.pop()

        return False if record else True

方法二:使用字典

class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        mapping = {
            '(': ')',
            '[': ']',
            '{': '}'
        }
        for item in s:
            if item in mapping.keys():
                stack.append(mapping[item])
            elif not stack or stack[-1] != item: 
                return False
            else: 
                stack.pop()
        return True if not stack else False

心得收获 

两种方法其实思路是一样的,只是在入栈匹配的时候,一种是使用字典,一种是每种情况都写一遍,第一种更省空间,但是如果需要判断的情况很多可以考虑使用字典

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

思路

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

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

那么栈里应该放的是什么元素呢?

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

然后再去做对应的消除操作。 如动画所示:

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

从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。

方法一:使用栈

class Solution:
    def removeDuplicates(self,s:str) -> str:
        if not s :
            return None
        stack = []
        for index in range(len(s)):
            if stack and s[index] == stack[-1]:
                stack.pop()
            else:
                stack.append(s[index])

        return ''.join(stack)

方法二:使用双指针

class Solution:
    def removeDuplicates(self, s: str) -> str:
        res = list(s)
        slow = fast = 0
        length = len(res)

        while fast < length:
            # 如果一样直接换,不一样会把后面的填在slow的位置
            res[slow] = res[fast]
            
            # 如果发现和前一个一样,就退一格指针
            if slow > 0 and res[slow] == res[slow - 1]:
                slow -= 1
            else:
                slow += 1
            fast += 1
            
        return ''.join(res[0: slow])

标签:遍历,匹配,第十天,队列,随想录,括号,slow,return,stack
From: https://blog.csdn.net/m0_61698277/article/details/140726810

相关文章

  • 代码随想录 day 37 完全背包 | 零钱兑换 II | 组合总和 Ⅳ | 爬楼梯 (进阶)
    完全背包完全背包解题思路由于我们可以重复放入物体,那么在遍历背包重量时就必须从前往后遍历,因为这样就可以重复放入了,其余的部分和01背包相同知识点完全背包心得学会了如何解决纯完全背白零钱兑换II零钱兑换II解题思路和之前01背包求总数的思路相同,唯一的不同点在......
  • 关于链表、顺序表、栈和队列的一些总结
    关于链表、顺序表、栈和堆的一些总结1.顺序表2.链表2.1单向链表2.1带哨兵位双向循环链表3.栈4.队列1.顺序表2.链表2.1单向链表2.1带哨兵位双向循环链表3.栈4.队列......
  • 算法板子:滑动窗口——应用单调队列,找到窗口中的最小值与最大值
    #include<iostream>usingnamespacestd;constintN=1e6+10;inta[N];//q数组模拟单调队列;q数组存储原数组元素的下标;//递增单调队列的队头始终维护窗口中的最小值;队头存的是窗口中最小值的下标//递减单调队列的队头始终维护窗口中的最大值;队头存的......
  • 多线程实现阻塞队列
    今天面试被问到了,多线程实现阻塞队列,记录一下。1importjava.util.LinkedList;2importjava.util.Queue;3importjava.util.concurrent.locks.Condition;4importjava.util.concurrent.locks.ReentrantLock;56publicclassFixedSizeBlockingQueue<T>{7......
  • 第十天|栈与队列| 232.用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047. 删除字符串
    目录232.用栈实现队列225.用队列实现栈两个队列模拟栈实现思路1:实现思路2:实现思路3:一个队列模拟栈实现思路1:实现思路2:实现思路3:20.有效的括号1047.删除字符串中的所有相邻重复项方法1:使用Deque堆栈方法2:用字符串直接当作栈方法3:双指针Day10学习到用栈来解......
  • 代码随想录算法训练营第48天 | 序列问题最终篇
    115.不同的子序列https://leetcode.cn/problems/distinct-subsequences/description/代码随想录https://programmercarl.com/0115.不同的子序列.html#算法公开课https://leetcode.cn/problems/delete-operation-for-two-strings/description/https://programmercarl.com/05......
  • 代码随想录||day25 非递减子序列,全排列问题
    491非递减子序列力扣题目链接题目描述:给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。示例1:输入:nums=......
  • 代码随想录day24打卡|| 93复原ip地址 78子集| 90子集||
    93复原ip地址力扣题目链接题目描述有效IP地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。例如:"0.1.2.201" 和"192.168.1.1" 是 有效 IP地址,但是 "0.011.255.245"、"192.168.1.312" 和 "[email protected]" 是 无......
  • 代码随想录算法训练营第47天 | 动态序列11:序列专题2
    代码随想录算法训练营第天|1143.最长公共子序列https://leetcode.cn/problems/longest-common-subsequence/description/代码随想录https://programmercarl.com/1143.最长公共子序列.html#算法公开课1035.不相交的线https://leetcode.cn/problems/uncrossed-lines/descrip......
  • 代码随想录day11 || 150 逆表达式求值 239 滑动窗口最大值 347 前k最高频元素
    150逆波兰表达式计算funcevalRPN(tokens[]string)int{ //自己想是真的想不出来,看了视频之后有了思路 //本质上逻辑就是遇到数字入栈,遇到运算符号出栈两个元素然后计算再入栈,最终就是计算结果 stack:=Constructor() for_,val:=rangetokens{ //如果数字入......