题目重点:is_clean只说集合内是否有坏pair,任意多个关系不能丢一端继续搜。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 身份唯一,隐藏无向坏关系集合;is_clean(S)=True恰当S不包含完整坏边。
- 必须输出全部坏边,黑盒允许任意两元素子集,噪声/概率返回不在本合同。
解题路线
- 最直接对全部无序pair查一次,[a,b]不clean当且仅当该pair坏,所以得到完整边集。
- 这是O(n²)调用的正确基线,可解释为密集坏边Ω(n²)输出量下界。若稀疏且允许集合查询,可分组排除全clean区域,但成本依稀疏性而非无条件对数。
- 单坏对的二分定位不能简单重复“找到u就移除u”,因为u可能与多个其他点都坏,移除会漏余边。优化必须显式枚举或恢复所有关联边。
手动走一遍
坏边(a,b),(a,c),找到(a,b)后丢a会永远漏(a,c)。逐pair查询两条都能返回。全部clean仍要基线n(n−1)/2调用;集合预查可快速处理全clean,但其他情况需新证明。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from itertools import combinations
def all_pairs(items,is_clean):
items=list(items)
if len(items)!=len(set(items)):raise ValueError("unique identities required")
return [(a,b) for a,b in combinations(items,2) if not is_clean([a,b])]
复杂度
O(n²)黑盒调用与O(T)输出,输入O(n);若每pair调用固定成本,则时间相应二次。不能把oracle当免费后声称全算法O(T)。
易错点与追问
容易失分的边界
- 坏relation若有方向,查询[a,b]对称输入无法辨认方向,需要不同oracle。
- 若黑盒会受第三元素条件影响,pair基线不再等价。
继续深挖
- 稀疏坏图怎样递归交叉两组并用clean结果剪枝?
- 查询元素总量或响应延迟才是费用时怎样定义优化指标?
