Leetcode刷题-字符串20:有效的括号

题目

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

有效字符串需满足:

1、左括号必须用相同类型的右括号闭合。

2、左括号必须以正确的顺序闭合。
3、每个右括号都有一个对应的相同类型的左括号。

示例1:

输入:s = "()"
输出:true

示例2:

输入:s = "()[]{}"
输出:true

示例3:

输入:s = "(]"
输出:false

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

解题思路

法1:

首先应该注意到的是有效字符串的长度一定是偶数,所以当字符串长度为奇数时,直接返回False。

后续可借助 来实现:

我们遍历给定的字符串s时,当我们遇到一个左括号时,在后续的遍历中我们将需要一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此我们可以将这个左括号放入栈顶。

当遇到一个右括号时,我们需要将一个相同类型的左括号闭合,此时,我们可以取出栈顶的左括号来判断它们是否为相同类型的括号。如果不是相同的类型,或者栈中并没有左括号(为空),则字符串s无效,返回False。

因为第一个是右括号时,字符串肯定是无效的,所以下面列出当第一个为左括号的情况下(即指针指到第二个括号时,栈不为空)对字符串进行遍历、判断的过程:

在这里,为了快速判断括号的类型,我们可以借助字典进行,字典的键为左括号,值为相对应的右括号。

遍历结束后,如果栈中没有左括号,说明字符串中所有的左括号都完成了闭合,字符串s有效,返回True,否则返回False。

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        #首先判断字符串长度
        if len(s) % 2 != 0 :
            return False
        
        #构造字典
        dict = { "(" : ")" , "[" : "]" , "{" : "}" }
        
        stack = []
        #遍历字符串
        for i in s:
            if i in dict:
                stack.append(i) #遇到左括号入栈
            else:
                if stack != [] and i == dict[stack[-1]]:
                    stack.pop() #遇到右括号,当栈非空,且当前括号与栈顶的左括号配对,即该左括号在字典中所对应的右括号一致时,出栈(消去该左括号)
                else:
                    return False
        #遍历结束,当栈空时,说明左括号全部配对完成
        if stack == []:
            return True
        else:
            return False

法2:

后面在评论区发现了一个执行更快、内存消耗更低的方法,以下是评论区大佬“代码随想录”的解题思路及代码:

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

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

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

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

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

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。
  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。

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

动画如下:

20.有效括号

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

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

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

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

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

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

#仅使用栈,更省空间
class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack = []
        for i in s:
            if i == '(':
                stack.append(')')
            elif i == '[':
                stack.append(']')
            elif i == '{':
                stack.append('}')
            #遇到右括号,当栈为空或者当前右括号与栈顶的右括号不一样时,字符串无效
            elif not stack or i != stack[-1]:
                return False
            #遇到右括号,栈不为空且当前右括号与栈顶的一样,匹配成功,将栈顶的右括号出栈
            else:
                stack.pop()
        
        return True if not stack else False

 

小知识

在字典dict = { key:value }中,只能通过key作为索引来获取其对应的值。其它常见应用如下:

以下内容引自CSDN博主「目元」的原创文章,遵循CC 4.0 BY-SA版权协议,转载附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yaoyuanna/article/details/126009259

1、通过key来遍历字典:

my_dict = {
     "小明":80,
     "小强":90,
     "小刚":100
}
#通过 for  key  in  dict 可以获取字典中所有的键
for key in my_dict :
    print(key,":",my_dict[key])
#输出结果
小明:80
小强:90
小刚:100

2、遍历key

my_dict = {
     "小明":80,
     "小强":90,
     "小刚":100
}
#字典中自带keys()方法获取所有的key
keys = my_dict.keys()
for key in keys:
    print(key)
#输出结果
小明
小强
小刚

3、遍历value值

my_dict = {
     "小明":80,
     "小强":90,
     "小刚":100
}
#字典中自带values()方法获取所有的value
values = my_dict.values()
for value in values:
    print(value)
#输出结果
80
90
100

4、遍历字典项

my_dict = {
     "小明":80,
     "小强":90,
     "小刚":100
}
#字典中提供items()方法可以获取字典中的所有键值对
items = my_dict.items()
for item in items:
    print(item)
#输出结果
("小明",80)
("小强",90)
("小刚",100)

5、通过字典项遍历key和value

my_dict = {
     "小明":80,
     "小强":90,
     "小刚":100
}
for key,value in my_dict.items():
    print(key,":",value)
#输出结果
 小明:80
 小强:90
 小刚:100

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值