
本文详解如何准确判断仅含圆括号、方括号和花括号的字符串是否有效,指出直接配对索引法的逻辑缺陷,并提供基于栈的标准解法,附可运行代码与关键注意事项。
本文详解如何准确判断仅含圆括号、方括号和花括号的字符串是否有效,指出直接配对索引法的逻辑缺陷,并提供基于栈的标准解法,附可运行代码与关键注意事项。
括号匹配问题看似简单,但极易因逻辑假设不当导致错误。题设要求验证字符串中三种括号 '(', ')', '[', ']', '{', '}' 是否满足:① 每个闭括号必须对应同类型开括号;② 开括号必须按正确顺序关闭(即后进先出);③ 所有括号均被完整配对。
原代码试图通过固定步长(2 * index + 1 和 2 * index + 2)逐对检查相邻字符,存在两个根本性错误:
- 索引越界与错位:s.charAt(2 * index + 2) 在 index = s.length()/2 - 1 时可能超出字符串边界(如 "()" 长度为 2,s.length()/2 = 1,则 2*0+2 = 2,而合法索引仅为 0 和 1),且 charAt() 索引从 0 开始,非 1;
- 忽略嵌套结构:该方法仅检查“相邻成对”,无法处理 [()]、{[()]} 等嵌套情形——这类结构中开闭括号不连续,但必须遵循栈式后进先出原则。
✅ 正确解法是使用栈(Stack):遍历字符串,遇开括号入栈;遇闭括号时,若栈为空或栈顶不匹配,则无效;否则弹出栈顶。最终栈为空即为有效。
以下是 Java 标准实现:
import java.util.*;
class Solution {
public boolean isValid(String s) {
// 使用 Map 定义括号映射关系(开→闭)
Map<character character> pairs = new HashMap();
pairs.put('(', ')');
pairs.put('[', ']');
pairs.put('{', '}');
Stack<character> stack = new Stack();
for (char c : s.toCharArray()) {
if (pairs.containsKey(c)) {
// 开括号:入栈
stack.push(c);
} else {
// 闭括号:检查栈是否为空,及栈顶是否匹配
if (stack.isEmpty() || pairs.get(stack.pop()) != c) {
return false;
}
}
}
// 所有开括号均被匹配,栈应为空
return stack.isEmpty();
}
}</character></character>
? 关键注意事项:
- 不要依赖字符串长度为偶数作为充分条件(虽为必要条件,但 "(((" 长度为奇数已可快速返回 false,但偶数长度如 "(]" 仍需栈验证);
- 使用 Stack 或 Deque(推荐 ArrayDeque 替代 Stack,因后者已过时且性能较差);
- 映射表键值类型必须为 Character(而非 String),避免 charAt() 返回 char 与 String 类型不匹配;
- 边界处理:空字符串 "" 是有效的(返回 true),单个括号(如 "(")必然无效。
该算法时间复杂度为 O(n),空间复杂度最坏为 O(n)(全为开括号),是解决括号匹配问题的经典且鲁棒方案。











