问题描述
给定一个只包括 '(', ')', '{', '}', '[', ']' 的字符串, 判断字符串是否有效.
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合.
- 左括号必须以正确的顺序闭合.
注意空字符串可被认为是有效字符串.
题目地址:https://leetcode-cn.com/problems/valid-parentheses/
(看了评论才知道是B站开发岗面试题)
示例
输入: "()"
输出: true
输入: "()[]{}"
输出: true
输入: "(]"
输出: false
输入: "([)]"
输出: false
输入: "{[]}"
输出: true
解答
思路一
class Solution:
    def isValid(self, s):
        while '{}' in s or '()' in s or '[]' in s:
            s = s.replace('{}', '')
            s = s.replace('[]', '')
            s = s.replace('()', '')
        return s == ''
对于正确的来说, 每次都能去掉一对括号, 最后就成了空.
思路二
其实这个题主要是考大家关于栈的应用
原理
- 栈先入后出特点恰好与本题括号排序特点一致, 即若遇到左括号入栈, 遇到右括号时将对应栈顶左括号出栈, 则遍历完所有括号后 - stack仍然为空;
- 建立哈希表 - dic构建左右括号对应关系:- key左括号,- value右括号;这样查询 2 个括号是否对应只需 $O(1)$ 时间复杂度;建立栈- stack, 遍历字符串- s并按照算法流程一一判断.
流程
如果 c 是左括号, 则入栈 push;
否则通过哈希表判断括号对应关系, 若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应, 则提前返回 false.
提高算法效率
提前返回false
- 边界问题栈 - stack为空: 此时- stack.pop()操作会报错;因此, 我们采用一个取巧方法, 给 stack 赋初值- ?, 并在哈希表- dic中建立- key:- '?',- value:- '?'的对应关系予以配合. 此时当- stack为空且- c为右括号时, 可以正常提前返回- false;
- 字符串 - s以左括号结尾: 此情况下可以正常遍历完整个- s, 但 stack 中遗留未出栈的左括号;因此, 最后需返回- len(stack) == 1, 以判断是否是有效的括号组合.
时间复杂度
- 时间复杂度 $O(N)$:正确的括号组合需要遍历 11 遍 s;
- 空间复杂度 $O(N)$:哈希表和栈使用线性的空间大小.
示意图

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