博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Leetcode 20. 有效的括号

Posted on 2020-06-08 14:24  秘密小鱼  阅读(126)  评论(0)    收藏  举报

难度:简单

思路: 维护一个栈,遍历字符串的每一个字符,如果是左括号,压入栈中;如果是右括号,只有当它和栈顶的左括号相匹配时,原串才合法。如果当前的右括号和栈顶的左括号不匹配,返回False,如果匹配,将栈顶的左括号弹出,因为这个左括号找到了与其对应的右括号,对最终结果不再影响。持续这个操作,如果最后栈为空,那么说明所有的左括号都找到了与其对应的右括号,那么这个字符串为合法的,反之不合法。

 

代码:

class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'{':'}','(':')','[':']','?':'?'}
        st = ['?']
        for c in s:
            if c in dic:
                st.append(c)
            elif dic[st.pop()] != c:
                return False
        return len(st) == 1

首先创建一个字典dic,字典的键为左括号,字典的值为这个左括号所期待匹配的右括号。当遇到右括号时,用栈顶的左括号作为键查字典得到其期待的右括号,将这个两个右括号进行比较,如果相等,弹栈,不等,则返回False。最后判断栈是否为空,空则返回True,反之返回False。

 上述代码中在栈底压入了一个哨兵'?',其作用是:减少不必的边界检查。如果不加这个哨兵,当遇到右括号时,我们必须将栈顶的左括号弹栈进行匹配,如果这时栈空,那么弹栈会引发异常。基础的解决办法是每次弹栈前都判断栈是否为空。更好的做法是增加一个哨兵'?',栈为空时,栈底也有一个'?',那么弹栈和右括号必不匹配,因此返回False,这样就不会导致弹空栈的问题,因此弹栈之前不会判断栈是否为空了,。算是一种巧妙地优化。

复杂度分析:由于只遍历一次字符串,且每次弹栈比较都是O(1)的,因此时间复制度为O(n),其中n为字符串长度。