用"快刷四部曲"把 423 题(有效的括号序列)在 5 分钟内秒掉。
(快刷四部曲:① 抽象模型 → ② 最优算法 → ③ 边界/异常 → ④ 一行一行写代码)
① 抽象模型
只有 3 对符号:圆、方、花。
合法性 = "任意前缀中左括号数 ≥ 右括号数" 且 "最终左右数量相等" 且 "类型必须一一对应"。
→ 经典"栈"模型:遇到左括号就压栈,遇到右括号就看栈顶是否匹配。
② 最优算法
时间:O(n) 必须扫一遍。
空间:O(n) 最坏全左括号。
算法:
- 建哈希表 right2left:
')'→'(',']'→'[','}'→'{' - 栈 stk 只存左括号。
- 遍历字符 c:
- 如果是右括号:
-- 栈空 ⇒ false
-- 栈顶 ≠ right2left[c] ⇒ false
-- 否则弹栈 - 如果是左括号 ⇒ 压栈
- 如果是右括号:
- 最后栈空 ⇒ true,否则 false。
③ 边界/异常
- 空串 ⇒ true(题目隐含)
- 单字符 ⇒ false
- 数量奇数 ⇒ 提前 false(可剪枝,非必须)
④ 代码(Java 版,可直接粘到 LintCode)
java
public boolean isValid(String s) {
if (s == null || s.length() % 2 == 1) return false; // 奇数剪枝
Deque<Character> stk = new ArrayDeque<>();
Map<Character, Character> right2left = Map.of(
')', '(', ']', '[', '}', '{');
for (char c : s.toCharArray()) {
if (right2left.containsKey(c)) { // 右括号
if (stk.isEmpty() || stk.pop() != right2left.get(c)) {
return false;
}
} else { // 左括号
stk.push(c);
}
}
return stk.isEmpty();
}
复杂度:
时间 O(n),空间 O(n)。
写完,直接 Submit,一遍 AC。