DGX Cloud SDE / Senior Cloud Infra(不同帖子) · Phone Screen / HM

Nvidia FizzBuzz Map 追问:规则顺序与重复查询

合并 Nvidia DGX Cloud 的 FizzBuzz 与 Senior Cloud Infra 的数字到字母扩展信号,给出除数映射训练契约、多个规则同时命中与缓存取舍。

题目重点:合并 Nvidia DGX Cloud 的 FizzBuzz 与 Senior Cloud Infra 的数字到字母扩展信号,给出除数映射训练契约、多个规则同时命中与缓存取舍。

题意与假设

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

  • 训练版 map 的 key 是正整数除数、value 是输出字符串;对输入整数 n,把所有整除 n 的规则文字按除数升序拼接,无命中输出 n 的字符串。题目未固定规则优先级。
  • 允许输入数字为零或负数,Python `%` 用于整除判定;若实际面试只给 1..N,范围应以题面为准。
  • 重复查询可做 memo,但只有当 map 在缓存生命周期内不可变或版本化时才安全;题目未明确更新规则。

解题路线

  1. 先实现标准规则 `{3:'Fizz',5:'Buzz'}`,再把规则抽成有序 `(divisor,word)` 列表;每个查询扫描规则并拼接命中的文字。
  2. 必须先问同一数字命中多个规则时如何排序、map 重复除数/空字串如何处理。示例代码定义升序,不能把它当作 Nvidia 固定题面。
  3. 如果相同 n 查询很多且规则固定,用 `(rules_version,n)` 缓存输出;若只查询区间 1..N,可预计算。若除数有有限最小公倍数 L,结果形式对 n mod L 有周期性,但无命中时还要返回 n 本身,且 L 可能极大,不能盲目建整周期表。

手动走一遍

训练规则 `{3:'Fizz',5:'Buzz',7:'Pop'}`:n=15 命中 3/5,输出 FizzBuzz;n=21 命中 3/7,输出 FizzPop;n=8 无命中,输出 '8'。若规则改变,之前缓存的 15 必须失效或换版本键。

Python 参考实现

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

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

def fizzbuzz_with_rules(numbers, rules):
    """Training rule: concatenate matches in ascending divisor order."""
    if any(not isinstance(divisor, int) or divisor <= 0 for divisor in rules):
        raise ValueError("divisors must be positive integers")
    ordered = sorted(rules.items())
    result = []
    for number in numbers:
        label = "".join(str(word) for divisor, word in ordered if number % divisor == 0)
        result.append(label or str(number))
    return result

复杂度

R 条规则、Q 个查询,规则排序 O(R log R),逐次扫描 O(QR) 加输出长度;缓存对不同 n 至多 O(U) 条目和输出字节,U 为唯一查询数。若一次调用重复构造排序,应把有序规则放到可复用对象。

易错点与追问

容易失分的边界

  • 仅支持 3/5,map 追问无法扩展。
  • 多规则命中时迭代普通 map 却未定义输出顺序。
  • 规则可更新仍按旧规则缓存结果。
  • 把谐音题号确定为完整输入/输出规则,忽略题目缺失的 map 语义。

继续深挖

  • map 的 key 若不是除数,而是数字范围或优先级,应怎样重新建模?
  • 上亿次重复 query 的缓存容量和失效如何设计?
  • 要输出 1..N 时,流式生成比一次存全部结果有什么差别?
✓已复制微信号!