Implement sparse vector dot product
Company: Meta
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: Meta's sparse vector dot product question asks you to design a SparseVector class that stores only non-zero entries and computes dot products in time proportional to the number of non-zeros rather than the full vector length. It tests sparse data representation, two-pointer vs. hash-map trade-offs, and time/space complexity analysis.
Constraints
- 1 <= n <= 10^5 (n is the common length of nums1 and nums2)
- nums1.length == nums2.length == n
- -100 <= nums1[i], nums2[i] <= 100
- Most entries are zero (the vectors are sparse)
Examples
Input: ([1,0,0,2,3], [0,3,0,4,0])
Expected Output: 8
Explanation: Overlapping non-zeros only at index 3: 2*4 = 8. Index 0 (1 vs 0) and index 4 (3 vs 0) contribute nothing.
Input: ([0,1,0,0,0], [0,0,0,0,2])
Expected Output: 0
Explanation: The two non-zeros sit at different indices (1 and 4), so there is no overlap and the dot product is 0.
Input: ([0,1,0,0,2,0,0], [1,0,0,0,3,0,4])
Expected Output: 6
Explanation: Only index 4 overlaps: 2*3 = 6. The non-zeros at indices 1, 0, and 6 have no counterpart.
Input: ([], [])
Expected Output: 0
Explanation: Edge case: empty vectors have no entries, so the dot product is 0.
Input: ([0,0,0], [0,0,0])
Expected Output: 0
Explanation: Edge case: all-zero vectors produce empty sparse representations and a dot product of 0.
Input: ([5], [3])
Expected Output: 15
Explanation: Single shared non-zero at index 0: 5*3 = 15.
Input: ([-1,0,2,0,-3], [4,0,-5,0,6])
Expected Output: -32
Explanation: Negatives: index 0 gives -1*4 = -4, index 2 gives 2*-5 = -10, index 4 gives -3*6 = -18; total -32.
Input: ([1,2,3], [4,5,6])
Expected Output: 32
Explanation: Fully dense vectors: 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32. The sparse approach still works when nothing is zero.
Hints
- Don't store the zeros. Keep only the (index, value) pairs where the value is non-zero, so storage is proportional to the number of non-zeros, not n.
- Because the dense array is already in index order, the list of non-zero (index, value) pairs comes out sorted by index for free.
- With both pair lists sorted by index, run a two-pointer merge: when both pointers are at the same index, multiply and accumulate; otherwise advance the pointer at the smaller index. This costs O(L + R).
- Alternative: store one vector as a hash map {index: value} and iterate over the smaller vector's non-zeros, looking each index up in the larger map for O(min(L, R)) average time — this handles a sparse-vs-dense mix well.