一、核心思路
利用栈后进先出的特性,匹配括号 “先开启、后闭合” 的规则:
-
建立映射表:右括号 → 对应左括号,方便快速查找配对;
-
遍历字符串:
- 碰到左括号,直接压入栈;
- 碰到右括号:栈为空 / 栈顶括号和当前右括号不匹配 → 直接返回 false;匹配成功则弹出栈顶;
-
遍历结束:栈必须为空,代表全部左括号都完成配对。
二、Java 代码(带注释)
class Solution {
public boolean isValid(String s) {
// 右括号映射到对应的左括号
Map<Character, Character> map = new HashMap<>();
map.put(')', '(');
map.put('}', '{');
map.put(']', '[');
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
// 当前字符是右括号
if (map.containsKey(c)) {
// 栈空 或者 栈顶元素和需要的左括号不一致,配对失败
if (stack.isEmpty() || stack.pop() != map.get(c)) {
return false;
}
} else {
// 左括号,入栈
stack.push(c);
}
}
// 栈为空说明所有左括号都找到匹配的右括号
return stack.isEmpty();
}
}
三、实例推演(s = "()[]{}")
| 当前字符 | 操作 | 栈状态 |
|---|---|---|
( | 左括号入栈 | [ '(' ] |
) | 右括号,栈顶(匹配,弹出 | [] |
[ | 左括号入栈 | [ '[' ] |
] | 右括号,栈顶[匹配,弹出 | [] |
{ | 左括号入栈 | [ '{' ] |
} | 右括号,栈顶{匹配,弹出 | [] |
遍历结束,栈为空 → 返回 true
四、复杂度分析
- 时间复杂度:(O(n)),n 为字符串长度,每个字符仅遍历一次
- 空间复杂度:(O(n)),最坏情况全部是左括号,栈保存全部字符
五、易错点总结
- 先出现右括号,栈为空,直接判定无效;
- 遍历结束栈不为空,存在多余左括号,返回 false;
- 括号类型不匹配,例如
(],直接返回 false。
六、个人感悟
栈非常适合处理这种嵌套、顺序匹配类问题,核心就是 “后进先出”,最后打开的括号必须最先闭合。用 map 反向映射右括号,代码写起来会更简洁。