在编译器、表达式求值、代码格式化等场景中,我们经常需要判断括号是否成对匹配且顺序正确 。这是一个经典的栈(Stack)应用问题。
一、问题描述
给定一个字符串,判断其中的括号是否匹配。括号可能包括:
- •
()
圆括号 - •
[]
方括号 - •
{}
花括号
要求:
- • 每个左括号必须有对应的右括号
- • 括号必须按正确的嵌套顺序闭合
示例
输入 | 输出 |
---|---|
"()" | true |
"([]{})" | true |
"(]" | false |
"([)]" | false |
"{[()()]}" | true |
二、算法思路
-
- 使用栈保存未匹配的左括号
-
- 遍历字符串:
-
- • 遇到左括号
(
、[
、{
→ 压入栈 - • 遇到右括号
)
、]
、}
→ 弹出栈顶元素,判断是否是对应的左括号 - • 若不匹配或栈为空 → 返回
false
- • 遇到左括号
-
- 遍历结束后,如果栈不为空 → 返回
false
- 遍历结束后,如果栈不为空 → 返回
-
- 否则 → 返回
true
- 否则 → 返回
三、Go语言实现
go
package main
import (
"fmt"
)
func IsValidBrackets(s string) bool {
stack := []rune{}
pairs := map[rune]rune{
')': '(',
']': '[',
'}': '{',
}
for _, ch := range s {
switch ch {
case '(', '[', '{':
stack = append(stack, ch) // push
case ')', ']', '}':
if len(stack) == 0 || stack[len(stack)-1] != pairs[ch] {
return false
}
stack = stack[:len(stack)-1] // pop
}
}
return len(stack) == 0
}
func main() {
tests := []string{"()", "([]{})", "(]", "([)]", "{[()()]}"}
for _, t := range tests {
fmt.Printf("%s -> %v\n", t, IsValidBrackets(t))
}
}
输出
rust
() -> true
([]{}) -> true
(] -> false
([)] -> false
{[()()]} -> true
四、复杂度分析
- • 时间复杂度:O(n),只需一次遍历
- • 空间复杂度:O(n),栈最多存储 n 个字符
五、进阶扩展
✅ 1. 增加其他符号
可以扩展 pairs 表,支持 <>
或自定义符号。
✅ 2. 忽略非括号字符
在表达式中可能包含数字、运算符,可以在 switch 中只处理括号。
✅ 3. 处理大规模数据
当输入很大时,可以考虑流式处理(分块判断)。
六、总结
通过本篇案例,你学习了:
- • 使用栈解决括号匹配问题
- • Go 语言中
map
、slice
的基本操作 - • 如何分析算法的时间和空间复杂度
栈的应用非常广泛,除了括号匹配,还可用于表达式求值、撤销操作、DFS搜索等场景。