SWE · Coding

黑盒找全部坏数对:两元素查询基线与单坏对区别

is_clean只说集合内是否有坏pair,任意多个关系不能丢一端继续搜。

题目重点:is_clean只说集合内是否有坏pair,任意多个关系不能丢一端继续搜。

题意与假设

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

  • 身份唯一,隐藏无向坏关系集合;is_clean(S)=True恰当S不包含完整坏边。
  • 必须输出全部坏边,黑盒允许任意两元素子集,噪声/概率返回不在本合同。

解题路线

  1. 最直接对全部无序pair查一次,[a,b]不clean当且仅当该pair坏,所以得到完整边集。
  2. 这是O(n²)调用的正确基线,可解释为密集坏边Ω(n²)输出量下界。若稀疏且允许集合查询,可分组排除全clean区域,但成本依稀疏性而非无条件对数。
  3. 单坏对的二分定位不能简单重复“找到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结果剪枝?
  • 查询元素总量或响应延迟才是费用时怎样定义优化指标?
✓已复制微信号!