MLE / Infra SWE · Phone Coding

LinkedIn MultiDimArray 求和:getDims/get 接口下遍历任意维度

按维数笛卡尔积生成下标,比较递归与迭代写法,处理空维、零维和 API 调用成本。

题目重点:按维数笛卡尔积生成下标,比较递归与迭代写法,处理空维、零维和 API 调用成本。

题意与假设

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

  • 每维大小为非负整数,索引从 0 到 d-1;get 为确定性读操作。任一维为 0,则没有元素、总和 0;零维 [] 当标量调用 get([]) 一次,这一点题目未说明,必须问接口。
  • 训练代码不预设元素一定是 int 以外的类型,但总和需支持加法;题目函数注解 int,实际类型当轮确认。

解题路线

  1. 读取 dims 一次,生成每个维度 range(d) 的笛卡尔积。对每组索引调用 get(list(indices)),累加返回值。
  2. 递归写法可维护一个长度 D 的 index buffer,在第 k 维循环 0…dims[k)-1,第 D 层调用 get;迭代写法可把索引当 mixed-radix counter,逐维进位。两者都访问恰好所有元素一次。
  3. 如果 get 是远程 API,算法仍需 P=∏dims 次逻辑读取,但可以询问批量/切片接口并按相邻维度批读,避免 P 次网络 RTT;并行读要遵守限流。
  4. dims 很长时递归可能超栈,训练代码用迭代 product。长度为 0 的维度是空数组,不应访问 get。

手动走一遍

dims=[2,2,3] 产生 12 组索引,从 [0,0,0] 到 [1,1,2],每个 get 一次后求和。dims=[2,0,3] 无任何合法索引,返回 0;dims=[] 在训练约定下读唯一标量 get([])。

Python 参考实现

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

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

from itertools import product


def array_sum(multidim_array) -> int:
    """Requires getDims() and get(indices). Empty dimensions have no cells."""
    dims = multidim_array.getDims()
    if any(d < 0 for d in dims):
        raise ValueError("negative dimension")
    total = 0
    for indices in product(*(range(d) for d in dims)):
        total += multidim_array.get(list(indices))
    return total

复杂度

D 维、P=∏dᵢ 个元素:O(PD) 下标生成/复制时间加 P 次 get,迭代工作空间 O(D)(不计 API 内部缓冲)。如果传入 list 每次复制 D 项,不能只说 O(P)。8,000 组随机形状与独立线性存储求和对照通过。

易错点与追问

容易失分的边界

  • 把维数之和当元素个数。
  • 忘记某一维为 0 时数组为空。
  • 重复调用 getDims 造成远端开销。
  • 在循环复用可变 indices 对象而异步 get 尚未消费。
  • 未核对零维代表标量还是空集合。

继续深挖

  • 若 get 有网络延迟,如何批量读取?
  • 稀疏数组只有非零位置可枚举时还遍历全部 P 吗?
  • 如果维度特别多导致 P 溢出,如何防护?
  • 负维或动态维度变化时如何处理?
✓已复制微信号!