返回
初探 LeetCode 678:如何判断一个括号字符串是否有效?
前端
2024-01-12 04:22:58
算法背景
在处理数据结构和算法问题时,经常遇到的一个经典问题是验证一组括号是否匹配。这类问题不仅出现在理论研究中,在实际开发中也非常常见,比如解析表达式、检查代码语法等场景。LeetCode 第678题“有效的括号字符串”就是其中一个典型示例。
理解题目
此问题的核心在于判断给定的包含三种类型括号('(', ')', '', ''可表示任意字符)的字符串是否有效。一个有效的括号字符串需满足以下规则:
- 每个左括号 '(' 必须有相应的右括号 ')'。
- 每个左方括号 '[' 必须有相应的右方括号 ']'。
- 每个左大括号 '{' 必须有相应的右大括号 '}'。
- '*' 可以代表任意字符,包括空字符串。
解决方案:双栈法
使用栈结构的原理
栈是一种后进先出(LIFO)的数据结构。在验证括号有效性时,可以通过一个栈来存储未匹配的左括号。当遇到右括号时,检查并移除对应的左括号。如果最终所有左括号都能找到相应的右括号,则整个字符串是有效的。
代码实现
Python 示例代码
def checkValidString(s: str) -> bool:
left_parentheses, star = [], []
# 遍历每个字符,遇到左括号或*则入栈
for i in range(len(s)):
if s[i] == '(':
left_parentheses.append(i)
elif s[i] == '*':
star.append(i)
else: # 遇到右括号')'
if len(left_parentheses) > 0:
left_parentheses.pop()
elif len(star) > 0:
star.pop()
else:
return False
# 处理剩余未匹配的左括号
while len(left_parentheses) > 0 and len(star) > 0:
if left_parentheses[-1] < star[-1]:
left_parentheses.pop()
star.pop()
else:
return False
return len(left_parentheses) == 0
# 测试代码
print(checkValidString("(*)")) # True
print(checkValidString("(*))")) # True
操作步骤
- 遍历字符串,使用两个栈分别存储左括号和星号的位置。
- 当遇到右括号时,优先匹配左侧栈中的元素;若左侧为空,则尝试匹配星号栈中记录的位置。
- 完成遍历后,处理可能未被匹配的左括号,确保其索引位置小于任意一个星号。
复杂度分析
- 时间复杂度:O(n),n为字符串长度。每个字符至多被检查和操作一次。
- 空间复杂度:O(n)。在最坏情况下,所有字符都是左括号或星号,需要使用两个栈存储其位置。
注意事项
- 需要确保栈操作中的元素索引顺序正确,避免越界访问。
- 使用多个变量来追踪未匹配的元素数量和类型(如左括号、星号),有助于简化逻辑并提高效率。
通过上述方法,我们可以有效判断一个包含多种括号类型的字符串是否有效。这种方法不仅适用于LeetCode 678题,也能广泛应用于其他涉及括号匹配的问题中。