SDE · Technical Coding

Bloomberg 年龄好友请求:有向计数、同龄去自己与频次优化

按题目 B∈(0.5A+7,A] 的条件统计有向请求;频次配对时同龄须减去自请求。

题目重点:按题目 B∈(0.5A+7,A] 的条件统计有向请求;频次配对时同龄须减去自请求。

题意与假设

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

  • 一笔请求是发送者 A→接收者 B 的有向 pair,同一人不能请求自己;输入年龄为非负整数。
  • 只采用题目明示条件,不额外引入其他年龄限制;B 的上界包含 A,下界严格大于 0.5A+7。

解题路线

  1. 先给 O(n²) 人对 oracle:遍历 i≠j,满足 2B>A+14 且 B≤A 就 +1,乘 2 避免浮点。
  2. 建 age→count;遍历出现过的年龄 A/B。A≠B 且合法时贡献 count[A]×count[B];A=B 时贡献 count[A]×(count[A]−1)。
  3. 年龄值域若很小可建前缀频次,把 A 允许范围的接收者数一次查出,再减掉自己;是否值得由值域上限决定。
  4. 边界测 A=14/15、同龄 1 人/2 人、B 恰等于半数+7 和 B>A。

手动走一遍

年龄 [16,16,17]:16→16 可发 2 笔;17→16 两人各一笔共 2;17→17 自己禁止,所以总 4。对 16,0.5×16+7=15,接收者 16 合法。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from collections import Counter


def count_friend_requests(ages):
    """Directed requests: B > A/2+7 and B <= A; no self requests."""
    frequencies = Counter(ages)
    total = 0
    for age_a, count_a in frequencies.items():
        for age_b, count_b in frequencies.items():
            if 2 * age_b <= age_a + 14 or age_b > age_a:
                continue
            total += count_a * (count_b - 1 if age_a == age_b else count_b)
    return total

复杂度

U 种不同年龄时频次解 O(n+U²) 期望时间、O(U) 空间;若已知年龄值域很小可用前缀和降至 O(n+V)。

易错点与追问

容易失分的边界

  • 把有向 pair 当无向组合。
  • 同龄频次平方却忘减自身。
  • 把严格下界写成 ≥。
  • 未经题目授权加入额外业务年龄规则。

继续深挖

  • 年龄值域有限怎样 O(n+V)?
  • 年龄数据流动态更新怎样维护总数?
  • 若要列出请求 pair 而非计数?
✓已复制微信号!