从零开始刷算法-栈-括号匹配

题目理解

我们需要判断一个字符串中的括号是否成对且顺序匹配,比如:

cpp 复制代码
输入:"({[]})" → true
输入:"([)]"   → false

从直觉上,这就是"遇到左括号就入栈,遇到右括号就出栈匹配 "的过程。栈这种后进先出(LIFO)的结构,天然适合这种成对匹配的问题。

解题核心思路

  1. 遇到左括号:入栈

  2. 遇到右括号:检查栈顶是否匹配

    • 栈空:说明多了右括号(例如 ")(")

    • 不匹配:说明类型不对(例如 "(]")

  3. 遍历完后,栈必须为空

    如果还剩左括号没匹配上,那也是不合法的。


关于 unordered_map 的关键设计

很多题解都是这样定义:

cpp 复制代码
unordered_map<char, char> mp = {{')', '('}, {']', '['}, {'}', '{'}};

这表示「右括号」是 key,「左括号」是 value。
为什么不反过来写?

因为我们匹配动作发生在遇到右括号时:

cpp 复制代码
if (mp.contains(c)) { // c 是右括号
    // 取出对应的左括号
    if (st.empty() || st.top() != mp[c]) return false;
    st.pop();
}

也就是说,我们要通过当前的右括号 c 找到它应当匹配的左括号 mp[c]。

所以 key 必须是右括号,这是逻辑上最自然的一种映射方式。

代码实现

cpp 复制代码
class Solution {
    // 思路: 遇到左括号进stack,遇到右边出stack
    unordered_map<char, char> mp = {
        {')', '('}, {']', '['}, {'}', '{'}
    }; 
public:
    bool isValid(string s) {
        if (s.length() % 2) return false; // 奇数长度一定不匹配
        
        stack<char> st;
        for (char c : s) {
            if (!mp.contains(c)) {
                // 左括号入栈
                st.push(c);
            } else {
                // 右括号时进行匹配
                if (st.empty() || st.top() != mp[c]) {
                    // 注意这里 empty() 要放在前面!
                    return false;
                }
                st.pop();
            }
        }
        return st.empty(); // 最后栈必须为空
    }
};

两个易错点总结

  1. 奇数长度直接返回 false

    因为每对括号都需要两个字符。

  2. st.empty() 判断要放在前面

    否则会先访问 st.top() 导致越界错误。

小结

这个题其实是典型的**"栈 + 哈希"组合拳**:

  • 哈希表解决"匹配关系";

  • 栈解决"嵌套顺序";

  • 顺序遍历 + 条件判断解决逻辑控制。

我认为它最大的难点不在代码,而在对操作顺序的理解反转 :

从"左括号匹配右括号",到"右括号查找左括号",这个思维变化一旦想通,后续几乎所有类似题都能一通百通。

相关推荐
Thomas.Sir5 小时前
第13课:MyBatis-Plus整合SpringBoot4.x,分页、条件查询、逻辑删除实战
java·spring boot
meiying88385 小时前
多快递公司快递单号批量查询接口怎么对接?Python 聚合查询实现
java·大数据·python
古法安卓5 小时前
Android-GPU压测工具
android·java·android studio
不积跬步无以至千里mmbb266 小时前
rust_analysis
开发语言·后端·rust
SL_staff6 小时前
10人团队如何用轻量私有化文档平台实现知识复用提效?技术视角拆解B/S架构下的协作闭环
java·开源·全栈
释厄6236 小时前
同性线套娃律——圆面积必然=1+2+...+n 的求和·圆心不与 π 相关
java·人工智能·算法·1024程序员节
暴力求解6 小时前
C++ ---继承(二)
开发语言·c++·算法
猫猫.1536 小时前
IO、存储、硬盘、文件系统详细总结
java·java-ee
陈飞EXCEL6 小时前
北京杰飞 IT 旗下妙码生花少儿Python编程上线两大学习系统
开发语言·python·学习
SL_staff7 小时前
设备离线时业务不中断:JVS-IOT高可用架构解析
java·物联网·产品