算法: 有效的括号
问题描述
给定一个只包括 '('
, ')'
, '{'
, '}'
, '['
, ']'
的字符串, 判断字符串是否有效.
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合.
- 左括号必须以正确的顺序闭合.
注意空字符串可被认为是有效字符串.
题目地址: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