SWE · Hiring Event Coding

Microsoft 括号匹配:三类括号的栈与嵌套顺序

用栈维护尚未闭合的开括号,遇闭括号必须匹配栈顶;区分数量相等与真正嵌套合法。

题目重点:用栈维护尚未闭合的开括号,遇闭括号必须匹配栈顶;区分数量相等与真正嵌套合法。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练输入只包含 ()[]{},空串视为合法;若混有普通字符,代码报错而非默认忽略。
  • 合法要求每个闭括号对应最近未闭合的同类开括号,且最终无剩余开括号。
  • 只返回 bool,不返回错误位置。

解题路线

  1. 扫描左到右,开括号入栈;闭括号必须与栈顶的对应开括号相同,否则立即失败。
  2. 扫描结束仅当栈空才成功。栈不变量是当前前缀所有尚未闭合的开括号,按嵌套由外到内排列。
  3. 正确性:任一合法匹配的闭括号必须先结束最内层尚未关闭的括号,恰是栈顶;失败时后续字符无法修复此前错误嵌套。

手动走一遍

'([])' 的栈依次入 '('、'[',再弹 '['、'(',合法;'([)]' 虽各类数量相同,但读到 ')' 时栈顶是 '[',立即失败;'(()' 结束仍有 '(',失败。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

"""Check whether (), [], and {} brackets are properly nested."""


def valid_brackets(text: str) -> bool:
    matching = {")": "(", "]": "[", "}": "{"}
    openings = set(matching.values())
    stack = []
    for character in text:
        if character in openings:
            stack.append(character)
        elif character in matching:
            if not stack or stack.pop() != matching[character]:
                return False
        else:
            raise ValueError("bracket-only input required")
    return not stack

复杂度

n 个字符各入/出栈最多一次,O(n) 时间;最坏全是开括号时 O(n) 空间。

易错点与追问

容易失分的边界

  • 只比较左右括号数量,不看嵌套顺序。
  • 闭括号时栈空仍尝试 pop。
  • 遍历结束不检查剩余开括号。
  • 输入允许普通字符与否未澄清,却把它们默默跳过。

继续深挖

  • 如何返回第一个错误下标与期望括号?
  • 输入流分块时如何跨块保存栈状态?
  • 若只有一种括号,为什么仍要追踪前缀余额非负?
✓已复制微信号!