← 双指针 · Two Pointer / 稀疏向量点积:两个有序列表对齐求交 待审核 3 / 7
Sparse Vector · 归并对齐

稀疏向量点积:两个有序列表对齐求交

一道常见的面试题:有两个超大向量,但绝大多数元素是 0(sparse),需要设计存储方式并求点积 ab=Σaibia\cdot b = Σ a_ib_i

存:只记非零项,存成一串 (index, value),按 index 升序。求点积:只有两边在同一维都非零的位置才对结果有贡献——其余项里总有一个 0,乘出来是 0。于是问题变成「在两个有序列表里找 index 相同的配对」,正是双指针归并:ij 各扫一个列表,谁的 index 小谁前进,index 相等时才把两个 value 相乘累加。

下方每个格子上排是下标 index、格内是值 value(即 向量[index] = value,没列出的下标都是 0)。默认 a 在下标 1,2,100 处非零、b 在 0,1,100 处非零——只有下标 1100 两处会真正相乘。

复杂度。两个指针各自只前进、不回头,合计走 O(len(a) + len(b)) 步——只跟非零项的数量挂钩,跟向量的「名义长度」(可能上亿)毫无关系。这正是稀疏表示的全部意义。

Follow-up:一个向量特别短时的处理。当 a 只有很少几项、b 很长时,与其让两个指针齐步归并,不如拿 a 的每个下标去 b 里二分查找(b 本就有序),复杂度降到 O(len(a)loglen(b))O(len(a) \cdot \log len(b))。这正是二分查找那页讲的内容——双指针家族里的对撞流派。