20. 有效的括号
问题描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s,判断字符串是否有效。有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例:
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([])"
输出:true
算法思路
栈的经典应用:
- 遍历字符串:处理每个字符
- 左括号入栈:遇到左括号
(,{,[时压入栈 - 右括号匹配:遇到右括号时:
- 若栈为空 → 无效(没有匹配的左括号)
- 弹出栈顶元素 → 检查是否匹配当前右括号
- 不匹配 → 直接返回 false
- 最终检查:遍历结束后,栈必须为空(所有括号完成匹配)
代码实现
import java.util.Stack;
class Solution {
/**
* 判断括号字符串是否有效
*
* @param s 输入字符串
* @return 是否有效
*/
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
// 情况1:遇到左括号 → 入栈
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
}
// 情况2:遇到右括号
else {
// 栈为空时遇到右括号 → 无效
if (stack.isEmpty()) {
return false;
}
// 弹出栈顶元素并检查匹配
char top = stack.pop();
if (c == ')' && top != '(') {
return false;
}
if (c == '}' && top != '{') {
return false;
}
if (c == ']' && top != '[') {
return false;
}
}
}
// 最终栈必须为空(所有左括号已匹配)
return stack.isEmpty();
}
}
算法分析
- 时间复杂度:O(n)
只需遍历字符串一次,每个字符处理时间为 O(1) - 空间复杂度:O(n)
栈的空间开销,最坏情况(全左括号)存储所有字符
算法过程
s = "[({}])" :
[→ 入栈(栈:[)(→ 入栈(栈:[, (){→ 入栈(栈:[, (, {)}→ 弹出{→ 匹配(栈:[, ()]→ 弹出(→ 不匹配!返回 false
s = "{[]}" :
{→ 入栈(栈:{)[→ 入栈(栈:{, [)]→ 弹出[→ 匹配(栈:{)}→ 弹出{→ 匹配(栈空)- 返回 true
边界条件处理
| 情况 | 处理方式 |
|---|---|
| 单字符 | 直接返回 false |
| 右括号开头 | 立即返回 false(栈空时遇到右括号) |
| 左括号结尾 | 最终检查栈非空 → 返回 false |
测试用例
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.isValid("()")); // true
System.out.println(solution.isValid("()[]{}")); // true
System.out.println(solution.isValid("(]")); // false
System.out.println(solution.isValid("([)]")); // false
System.out.println(solution.isValid("{[]}")); // true
System.out.println(solution.isValid("")); // true (边界:空字符串)
System.out.println(solution.isValid("[")); // false (边界:单左括号)
System.out.println(solution.isValid("]")); // false (边界:单右括号)
System.out.println(solution.isValid("{[()]}")); // true (嵌套括号)
}
关键点
-
栈的核心作用:
- 按顺序存储未匹配的左括号
- 保证最近打开的括号最先闭合(LIFO特性)
-
匹配逻辑:
if (c == ')' && top != '(') return false; // 小括号匹配 if (c == '}' && top != '{') return false; // 花括号匹配 if (c == ']' && top != '[') return false; // 方括号匹配 -
两个终结条件:
- 处理右括号时栈空 → 无效
- 遍历结束栈非空 → 无效
-
避免空栈异常:
if (stack.isEmpty()) return false; // 关键防御
常见问题
-
为什么用栈不用计数器?
三种括号类型混合时,计数器无法检测顺序错误(如([)]) -
如何处理
嵌套括号?
栈的 LIFO 特性天然支持嵌套结构(最近开括号必须最先闭合)
算法题:判断有效括号
51万+

被折叠的 条评论
为什么被折叠?



