题目重点:根据 Oracle 电面的两数组约束和 query 示例,建立位置表线性验证先后关系,并标明缺失节点与环的训练约定。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版验证 query 中出现的节点之间的直接约束;若约束一端不在 query 中,不据此判错,因为题目示例本身缺 5、8。
- query 中重复节点视为无效,before/after 数组长度必须相同,自环约束无效。若面试官要求 query 包含所有节点,需另加完整性检查。
解题路线
- 一次扫描 query 建 node→index 位置表;重复节点立即判无效。
- 逐对读取 before[i]→after[i],若两端都在 query,必须有 index(before)<index(after);若任一端缺失,按训练约定忽略。
- 这里检查给定顺序是否满足约束,不必先拓扑排序;若任务改为构造某个合法顺序,才用入度与拓扑排序并检测环。
- 对相同两节点之间冲突方向,两个不等式不可能同时成立,验证自然返回 false;自环即使节点缺失也视为不合理的约束输入。
手动走一遍
题目 A=[1,5,2,8]、B=[2,3,4,3],query=[1,2,3,4]。在 query 内可检验 1→2、2→4,均成立;5→3、8→3 因起点缺失按训练约定跳过,所以返回 true。若交换 1 与 2,则违反 1→2。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Validate the order of present query nodes against before/after constraints."""
def valid_partial_order(
before: list[int], after: list[int], query: list[int]
) -> bool:
if len(before) != len(after):
raise ValueError("Constraint arrays must have equal length")
positions = {node: index for index, node in enumerate(query)}
if len(positions) != len(query):
return False
for source, target in zip(before, after):
if source == target:
return False
if source in positions and target in positions:
if positions[source] >= positions[target]:
return False
return True
复杂度
query 长度 Q、约束数 E:建表与检查时间 O(Q+E),额外空间 O(Q)。若要求全图拓扑或传递闭包,复杂度与问题定义会改变。
易错点与追问
容易失分的边界
- 把“验证已有 query”误做成“生成拓扑序”,增加不必要的工作。
- 未经澄清就要求 query 包含所有端点,与题目公开示例不一致。
- 只按 query 相邻元素检查;非相邻的 before/after 约束同样必须满足。
继续深挖
- 若缺失任一约束端点都应判 false,应怎样修改,题目示例又会怎样?
- 若要输出任意合法完整顺序,如何检测有向环和处理多个零入度节点?
