题目重点:Nvidia System Software 面经要求验证数学表达式中的括号是否匹配;本文用栈处理圆、方、花括号,分析嵌套、顺序与额外语法追问。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版识别 `()`、`[]`、`{}` 三种括号;数字、运算符、变量名和空白不影响括号匹配。题目未列具体括号种类。
- 只验证括号配对与嵌套,不判断 `1+*2` 是否为合法数学表达式;空串或无括号表达式视为括号匹配。
- 输入不含会改变括号语义的字符串字面量或转义;若包含它们,先实现词法扫描,再将真正的括号 token 送入匹配器。
解题路线
- 从左到右扫描字符。遇左括号压入栈,遇右括号时必须与栈顶同类,否则立即返回不匹配;普通字符跳过。
- 扫描不变量:栈自底向上恰好是已读前缀中尚未配对的左括号,且它们必须按后进先出顺序闭合。
- 扫描完成后仅在栈为空时返回匹配。正确性分两类:右括号不匹配意味着任何后续字符都无法改变其已发生的错误嵌套;剩余左括号说明缺少结尾闭合。
手动走一遍
`a*(b+[c-{d/e}])`:依次压入 `(`、`[`、`{`,读到 `}`、`]`、`)` 依次弹出,结果为真。`([)]` 在第一个 `)` 遇到栈顶 `[`,立即为假;`a+(b` 到结束仍有 `(`,也为假。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Check (), [], and {} nesting inside an unquoted mathematical expression."""
def matching_brackets(expression):
pairs = {')': '(', ']': '[', '}': '{'}
openings = set(pairs.values())
stack = []
for char in expression:
if char in openings:
stack.append(char)
elif char in pairs:
if not stack or stack.pop() != pairs[char]:
return False
return not stack
复杂度
表达式长度 L、最大未闭合深度 D:时间 O(L),辅助栈空间 O(D),最坏 D=L。若只含一种括号可用计数器,但三种括号的交错嵌套需要栈。
易错点与追问
容易失分的边界
- 只比较各种括号左右数量,`([)]` 的数量相同却嵌套错误。
- 遇右括号先弹栈而未检查空栈,首字符为 `)` 时会抛异常。
- 到输入结尾就返回成功,漏掉残留的未闭合左括号。
- 把“括号匹配”扩展成完整表达式语法检查,却没有题面依据;这应作为独立追问。
继续深挖
- 若输入含字符串、注释或转义,先建立词法状态,只处理代码 token 中的括号。
- 若需要报错位置,栈保存括号与字符偏移;右括号不匹配时报告当前位置和期望字符,末尾报告剩余左括号位置。
- 若流式分块处理,保留未闭合栈作为跨块状态;多个分片直接各自独立返回 bool 不能正确合并。
