【题目】
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入: s = "()"
输出: true
示例 2:
输入: s = "()[]{}"
输出: true
示例 3:
输入: s = "(]"
输出: false
提示:
1 <= s.length <= 104s仅由括号'()[]{}'组成
【题目解析】
这个问题可以通过一种称为栈的数据结构来解决。栈是一种后进先出(LIFO)的数据结构,它只允许在一端(通常称为"顶部")进行添加数据(推入)和移除数据(弹出)。算法的核心思想是扫描字符串,每当遇到开括号时,将其推入栈中。每当遇到闭括号时,检查栈顶的元素。如果栈顶元素是与之匹配的开括号,就将其弹出栈;如果不匹配或栈为空,则字符串无效。如果在完成扫描后栈为空,则字符串有效。
class Solution:
def isValid(self, s: str) -> bool:
# 初始化一个栈
stack = []
# 创建一个映射,用于查找匹配的括号
bracket_map = {')': '(', '}': '{', ']': '['}
# 遍历字符串中的每个字符
for char in s:
# 如果是闭括号
if char in bracket_map:
# 弹出栈顶元素,若栈为空,则赋予一个虚拟的字符
top_element = stack.pop() if stack else '#'
# 如果栈顶元素与当前闭括号不匹配,则字符串无效
if bracket_map[char] != top_element:
return False
else:
# 如果是开括号,推入栈中
stack.append(char)
# 如果栈为空,则所有括号都有效匹配
return not stack
【总结】
适用问题类型: 有效的括号问题属于匹配类问题,其特点是需要检查一系列元素中是否存在合法的配对关系。这类问题广泛存在于编程语言的语法分析、文本编辑器的代码检查、以及日常开发中处理各类括号、标签和特殊字符的场景。此类问题的共同点是,对于每一个"开启"元素,都需要找到一个对应的"关闭"元素,并且它们的顺序必须正确。这不仅适用于简单的括号,也适用于比如 HTML 或 XML 标记的嵌套结构检查。
使用的算法: 本题的解法使用了栈这一数据结构的特性来解决问题。算法的核心是维护一个栈来跟踪未匹配的"开启"括号,当遇到一个"关闭"括号时,尝试从栈中弹出一个元素并检查它是否与之匹配。如果匹配,则继续处理字符串的下一个字符;如果不匹配或栈为空,则判定字符串为无效。有效的括号字符串意味着所有的"开启"括号在字符串中都找到了正确顺序的"关闭"括号。
算法细节:
-
创建一个映射,用于快速查找每个"关闭"括号对应的"开启"括号。
-
遍历字符串,使用栈跟踪所有"开启"括号。
-
遇到"开启"括号时,将其推入栈中。
-
遇到"关闭"括号时,检查栈顶元素是否匹配:
- 如果栈不为空且顶部元素匹配,弹出栈顶元素。
- 如果栈为空或顶部元素不匹配,返回 false。
-
完成遍历后,如果栈为空,则所有括号都匹配;否则,括号不匹配。
总结: 本题展示了栈在处理成对匹配问题中的应用,栈的后进先出(LIFO)特性使它成为处理此类问题的理想选择。该问题的解决方案展现了栈的简洁性和高效性,它在算法设计中的应用是多样的,包括但不限于括号匹配,还有函数调用栈、回溯算法、深度优先搜索等算法和数据结构的核心组成部分。掌握了栈的使用和相关算法,我们就能够有效地解决一类包含顺序和配对逻辑的问题。