【用栈解决括号匹配问题】JS 与 Python 解锁面试常客题!

96 阅读2分钟

🧠 引言

你可能见过这道题:

给定一个字符串,只包含 ()[]{}

判断括号是否有效配对,也就是:

  • 左右括号数量一致
  • 括号顺序正确

例如:"()[]{}" 是有效,"(]" 是无效

这其实是典型的栈应用题,也是算法面试中的高频项目。

本篇带你用 JS 和 Python 双解法,彻底掌握这道题的思路、实现、易错点和优化方式!


📌 一、题目描述(LeetCode 20)

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

输入: "(]"
输出: false

🧱 二、思路解析:用“栈”解决配对问题

✅ 核心逻辑:

  • 遇到左括号:入栈

  • 遇到右括号

    • 如果栈空 ❌ 错误
    • 弹出栈顶,检查是否和当前括号匹配

✅ 配对关系映射:

{
  ')': '(',
  ']': '[',
  '}': '{'
}

💻 三、JavaScript 实现

function isValid(s) {
  const stack = [];
  const map = {
    ')': '(',
    ']': '[',
    '}': '{'
  };

  for (let char of s) {
    if (['(', '[', '{'].includes(char)) {
      stack.push(char);
    } else {
      if (stack.pop() !== map[char]) {
        return false;
      }
    }
  }

  return stack.length === 0;
}

// 测试
console.log(isValid("()[]{}")); // true
console.log(isValid("(]"));     // false
console.log(isValid("([{}])")); // true

🐍 四、Python 实现

def is_valid(s):
    stack = []
    mapping = {')': '(', ']': '[', '}': '{'}

    for char in s:
        if char in mapping.values():
            stack.append(char)
        else:
            if not stack or stack.pop() != mapping[char]:
                return False

    return not stack

# 测试
print(is_valid("()[]{}"))  # True
print(is_valid("(]"))      # False
print(is_valid("([{}])"))  # True

🧪 五、边界与异常情况测试

输入输出说明
""true空字符串也是有效的
((((false所有括号没闭合
())(false顺序错误
([]){}true合法混合配对
((()))(()())true多层嵌套合法

⚠️ 六、易错点提醒

问题描述正确应对方式
弹出时栈已空(pop error)先判断栈是否为空再 pop
多余的左括号未清空判断最终 stack.length === 0
配对映射写错用 Map 显式定义匹配关系

📦 七、优化建议

  • 可用 Set 判断左括号成员
  • 可在遇到第一个右括号时提前 return false 提高效率
  • 字符量大时可用 switch 替代 if

🧩 八、拓展任务

  • 拓展支持 HTML 标签匹配(如 <div>...</div>
  • 解析表达式中的括号优先级结构
  • 写一个 IDE 插件检测不闭合括号

📚 总结一句话

括号匹配题看似简单,但背后其实是对“栈思想”最直接、最本质的考察之一!


📘 下一篇预告:

第11篇:【滑动窗口算法实战】JS 与 Python 解最小子串和最小覆盖子串问题!