提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
题目描述
原题的链接见:有效的括号。
题目理解
这个题目一看我的第一反应就是一个栈,左括号先进,相对应的右括号看作它自己的话,它就得先出。所以,这个题目应该是想考察一个栈数据结构的熟练使用。
P.S. 我记得上高中的时候,物理老师曾经说,如果你看到一道题目,你立马就明白出题的人想考察什么,想在哪里挖坑让你跳,那么你的水平就可以了。我想,在计算机编程领域里,这个道理也是同样适用的。
具体到这道题目里,就是考察一个略带变形了的栈数据结构。由于Python本身并不包含栈的数据结构,因此可以使用列表List来代替。可以通过.append()或者.extend()完成压栈的功能,可以通过.pop()来完成弹栈的功能。
我的代码
我的代码如下。在我的代码里,我用一个列表l用来记录压入栈内的括号,判断当这个括号是左括号时,就一直压入栈内;如果是右括号,那么就得分情况讨论:1,假如此时栈内是空的,意为着要么是第一个括号,要么前面的括号都已经凑成了完整的对子,所以此时直接return False即可,因为一个右括号开始的话永远也凑不成;2,如果当前压入栈内的右括号和栈内的最后一个括号加起来数值不为0,意为不匹配,那么肯定也是False;除此之外的第3种情况,就是匹配上了,匹配上了就弹栈,相当于抵消了前一个左括号,即.pop()操作。依次循环下去。。。
最后,栈l里头是空的话,说明全部匹配抵消完毕,所以就return not l刚好是True。
class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2 == 1:
return False
re = dict()
re['('] = 1
re[')'] = -1
re['['] = 2
re[']'] = -2
re['{'] = 3
re['}'] = -3
l = []
i = 0
while(i<len(s)):
if re[s[i]]>0:
l.extend([s[i]])
else:
if l == []:
return False
if re[s[i]] + re[l[-1]]:
return False
l.pop()
i += 1
return not l
这个程序效果还可以,整体上来说,性能已经很靠前了。当然还可以进一步提高,就是把while 换成for,对于这种要把整个列表都循环一遍,且中途没有什么特殊的终止条件的,选择用for比while好。
总结
今天这一道题,做的还算不错的主要原因有这么几点:
- 有效识别出了数据结构—栈,并使用Python里的列表相关操作实现了栈;
- 加入了散列表,使用散列表(也就是Python里的字典)来查找相应的元素,提高了查找速率;
- 设置了一点小技巧,用具体的一些数值来帮助判断是左括号还是右括号,以及这些括号是否匹配(官方代码里的设置也挺有技巧的,但我觉得一般人根本想不到,还是我这种正负相消更好理解一些)。