有效的括号

问题描述

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

有效字符串需满足:

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

  2. 左括号必须以正确的顺序闭合。

  3. 每个右括号都有一个对应的相同类型的左括号。

    示例 1:
    输入:s = "()"
    输出:true
    
    示例 2:
    输入:s = "()[]{}"
    输出:true
    
    示例 3:
    输入:s = "(]"
    输出:false
    

思路

首先看了看问题,发现不考虑括号嵌套的情况,那么放心大胆地借鉴最长公共前缀的思路,看看[的索引 +1 是不是]

class Solution:
    def isValid(self, s: str) -> bool:
        if '(' in s and ')' in s:
            return s.find('(') + 1 == s.find(')')
        elif '[' in s and ']' in s:
            return s.find('[') + 1 == s.find(']')
        elif '{' in s and '}' in s:
            return s.find('{') + 1 == s.find('}')
        else:
            return False

这也太笨了
用时60ms,这里还是使用了str.find()的方法,但是前提是要先判断某个括号在s里面。

试一试提交,完蛋,错误。
输入s = "(){}}{",正确答案False,输出了True,原来是大括号重复出现了,
str.find()方法只会返回第一个查找到的值的索引。emmmmm,看来要重新构思了。

好的没构思出来,问问chatgpt。

class Solution: def isValid(self, s: str) -> bool: 
	stack = [] 
	for c in s: 
		if c in ['(', '{', '[']: 
			stack.append(c) 
		elif not stack or abs(ord(c) - ord(stack.pop())) > 2: 
			return False 
	return not stack

这里先创建一个栈stack,对s中每个元素进行遍历,假如找到一个左括号,就用append方法将左括号压入栈中,接下来elif not stack or abs(ord(c)) - ord(stack.pop())) > 2 表示如果stack为空 or 不为空但c的ASCII值 - stack弹出字符的ASCII值 >2时,返回False

因为在 ASCII 编码中,‘(’、‘)’、‘{’、‘}’、‘[’ 和 ‘]’ 的数字值是连续的。例如,‘(’ 的 ASCII 值是 40,而 ‘)’ 的值是 41,它们之间的差为 1。同样,‘[’ 和 ‘]’ 之间的差为 2,‘{’ 和 ‘}’ 之间的差也为 2。

而栈的特性是后进先出,试想一下:

  1. 我遇到一个(,好的,压入stack
  2. 再往s的右边遍历,到第二位括号,现在stack肯定不为空嘛,从stack中弹出了一个值,就是刚刚第一个括号,检查两者ASCII值之差的绝对值,大于2肯定不连续,也就不匹配,小于2时,好的,这一对括号匹配到了,到下一个循环。
  3. 那现在stack又空了,再遇到左括号压入栈中,遇到右括号再把左括号弹出。
  4. 如果先遇到右括号,就是c不在['(', '[', '{']中,跳到elif,但是stack现在肯定是空的,直接False
  5. 假如全部匹配的话,stack肯定都弹完了,就return not stack,如果空的,就True,反之False

结果

用时40ms,内存16mb,击败51.72%和7.28%。

注意点和总结

stack.pop()是从栈顶弹出元素,也就是上一个进去的。
ord()方法能返回元素的ASCII值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值