#20 简单

有效的括号

在 LeetCode 上查看 ↗

🎧 语音讲解

开车或通勤时可听,跟着思路走一遍

速度

📋 题目描述

给定一个只包括 '('')''{''}''['']' 的字符串 s,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1

输入:s = "()"
输出:true

示例 2

输入:s = "()[]{}"
输出:true

示例 3

输入:s = "(]"
输出:false

示例 4

输入:s = "([])"
输出:true

示例 5

输入:s = "([)]"
输出:false

💭 模拟答题者思考

1. 我先写暴力:对每个右括号,向前找最近一个未匹配的左括号,看类型是否一致——能判断,但要反复扫描、标记已用字符,实现又慢又乱。

2. 重复在哪里?每次匹配的都是「离当前右括号最近、且尚未闭合」的左括号——这正是后进先出(LIFO)的结构。

3. 用栈:遇左括号压栈;遇右括号看栈顶是否是与之配对的左括号,是则弹出,否则无效。扫完后栈空才有效。

4. 细节:右括号来时栈不能为空;类型必须严格匹配,(]([)] 都会在匹配阶段失败。

5. 复杂度:每个字符最多入栈出栈各一次,时间 O(n);最坏全是左括号时栈长 O(n)。

🧠 变量语义(先读这三句再编码)

变量类型语义(三句法)
stklist / stack定义:存放尚未被匹配的左括号
维护:栈底到栈顶对应「从外到内、尚未闭合」的左括号序列
更新:遇左括号 push;遇右括号且匹配成功则 pop,否则直接判无效
pairsdict定义:右括号到左括号的映射(')'→'(' 等)
维护:固定不变,覆盖三种括号对
更新:无需更新,用 pairs[c] 查期望的栈顶左括号
cchar定义:当前扫描到的字符
维护:从左到右依次处理每个括号
更新:每轮循环取下一个字符,按左/右分支更新栈或提前返回 False

⌨️ 落码步骤

1. 建立右→左括号映射 pairs = {')':'(', ']':'[', '}':'{'}

2. 初始化空栈 stk = [],从左到右遍历每个字符 c

3. 若 c 是左括号(不在 pairs 的 key 中),stk.append(c)

4. 若 c 是右括号:栈空或 stk[-1] != pairs[c] 则返回 False,否则 stk.pop()

5. 遍历结束,返回 len(stk) == 0

💻 代码实现

class Solution:
    def isValid(self, s: str) -> bool:
        pairs = {')': '(', ']': '[', '}': '{'}
        stk = []
        for c in s:
            if c not in pairs:          # 左括号,等待匹配
                stk.append(c)
            elif not stk or stk[-1] != pairs[c]:  # 右括号无法配对
                return False
            else:
                stk.pop()
        return not stk
class Solution {
public:
    bool isValid(string s) {
        unordered_map<char, char> pairs = {
            {')', '('}, {']', '['}, {'}', '{'}
        };
        vector<char> stk;
        for (char c : s) {
            if (!pairs.count(c)) {       // 左括号,等待匹配
                stk.push_back(c);
            } else if (stk.empty() || stk.back() != pairs[c]) {
                return false;            // 右括号无法配对
            } else {
                stk.pop_back();
            }
        }
        return stk.empty();
    }
};
// 时间 O(n),空间 O(n)

📈 复杂度分析

时间复杂度 O(n)
空间复杂度 O(n)

⚠️ 常见坑

右括号来时忘记检查栈空:如 ")""]" 会直接访问空栈顶导致错误。

只判断「栈非空」不判断类型:(] 栈顶是 ( 却遇到 ],必须返回 False

遍历结束后忘记检查栈是否为空:"(""([(" 等左括号未闭合应判无效。

🔍 必测边界 Case

Case 1:单个左括号未闭合
s = "(" → false
Case 2:单个右括号无匹配
s = ")" → false
Case 3:嵌套与交叉
s = "([])" → true;s = "([)]" → false