题目重点:匹配三类括号嵌套,区分只计总数、非括号字符政策与流式验证。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 输入仅()[]{},空串合法,返回布尔;非括号字符报错,不静默过滤。
- 单类括号可以计数,但本训练有多类且要求嵌套顺序。复用Microsoft已验证标准栈示例,Amazon来源单列。
解题路线
- 读开括号push,闭括号必须有栈顶且与其类型配对,随后pop;扫完栈空才合法。不能只计三种净数量。
- 不变量:处理过的前缀尚未闭合括号按开启顺序在栈中,顶是下一个合法闭括号应匹配的最近开启。闭括号遇空栈代表前缀多关。
- 若遇([)],总数量均平衡但最近开启[被)关闭,立即false;扫描末尾剩开启同样false。算法每次消费当前字符,不需要不断拼接/删整串。
- 若需求是检查带字符串/注释的源代码括号,则lexer处理引用/escape/注释再送括号流,不能将本文忽略政策直接套代码语法。
- 流式可保栈跨chunk,只有输入完成才判断是否全关闭;单chunk结束栈非空不能提前报整串false。但发现已错匹配可立即拒绝。
手动走一遍
'{[()]}'合法、'([)]'非法、')('非法、'('最后未闭合。55,987个长度0..6括号串与独立反复消除相邻匹配对直到稳定的语法参考核对通过。
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
复杂度
O(n)时间,栈最坏O(n);单类计数O(1)状态,但三类任意嵌套需记顺序。独立消除参考仅用于小测试,反复replace不是生产线性方案。
易错点与追问
容易失分的边界
- 只计总数。
- 闭括号pop前不判空。
- 扫完忘检查栈空。
- 忽略引号里的括号当语法检查。
- chunk未完就提前判未闭合失败。
继续深挖
- 只有一种括号为何可用计数?
- 返回首次错误位置如何定义?
- 引号/escape的lexer状态如何跨chunk?
- 嵌套最大深度限制怎样加?
