Dot Product of Two Vectors (Dense, then Sparse)
Company: Whatnot
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
# Dot Product of Two Vectors (Dense, then Sparse)
You are given two integer vectors of the **same length** and must compute their **dot product** — the sum of the element-wise products.
For two vectors $a$ and $b$ of length $n$:
$$a \cdot b = \sum_{i=0}^{n-1} a_i \cdot b_i$$
## Part 1 — Dense vectors
Implement a function that takes two equal-length integer arrays `a` and `b` and returns their dot product as an integer.
**Examples**
- `a = [1, 0, 0, 2, 3]`, `b = [0, 3, 0, 4, 0]` -> `1*0 + 0*3 + 0*0 + 2*4 + 3*0 = 8`
- `a = [0, 1, 0, 0, 2, 0, 0]`, `b = [1, 0, 0, 0, 3, 0, 4]` -> `0 + 0 + 0 + 0 + 6 + 0 + 0 = 6`
- `a = [1, 2, 3]`, `b = [4, 5, 6]` -> `4 + 10 + 18 = 32`
## Part 2 — Sparse vectors (follow-up)
In practice the vectors are **very long but mostly zeros** (for example, length $10^7$ with only a few hundred non-zero entries). Storing and iterating over every position wastes time and memory.
Represent each vector as a list of `[index, value]` pairs for its **non-zero** entries only, **sorted by index in ascending order**, together with the logical length `n` of the vector. Compute the dot product using only the non-zero entries, so that the running time depends on the number of stored entries rather than on `n`.
**Sparse representation example**
The dense vector `a = [0, 5, 0, 0, 9]` (length `n = 5`) is represented as `[[1, 5], [4, 9]]`.
**Examples (sparse)**
- `a = [[1, 5], [4, 9]]`, `b = [[0, 2], [4, 3]]`, `n = 5`
(dense `a = [0,5,0,0,9]`, dense `b = [2,0,0,0,3]`) -> only index `4` overlaps -> `9 * 3 = 27`
- `a = [[0, 1], [2, 2]]`, `b = [[1, 4], [3, 5]]`, `n = 4`
(no shared non-zero index) -> `0`
## Constraints
- Both vectors have the same logical length `n`, with `1 <= n <= 10^7`.
- Element values fit in a signed 64-bit integer; the dot product is guaranteed to fit in a signed 64-bit integer.
- In the sparse representation, indices within a single vector are distinct and sorted ascending, and `0 <= index < n`.
- For the sparse case, aim for `O(k_a + k_b)` time and `O(1)` extra space (beyond the inputs), where `k_a` and `k_b` are the numbers of non-zero entries in `a` and `b` respectively. A hash-map lookup approach `O(k_a + k_b)` time with `O(min(k_a, k_b))` extra space is also acceptable; the two-pointer merge over the sorted index lists is the most space-efficient.
Quick Answer: This question assesses proficiency in array manipulation and algorithmic efficiency by asking for a vector dot product, first over dense arrays and then over a sparse representation. It tests the ability to recognize when a brute-force linear scan is wasteful and to design a two-pointer or hash-map approach that scales with the number of non-zero entries rather than total length. Such prompts are common in coding interviews to gauge both baseline correctness and optimization instincts for data-structure trade-offs.
Dot Product of Two Dense Vectors
You are given two integer vectors `a` and `b` of the **same length** `n`, stored as ordinary arrays. Compute and return their **dot product** — the sum of the element-wise products: `a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1]`.
**Examples**
- `a = [1, 0, 0, 2, 3]`, `b = [0, 3, 0, 4, 0]` -> `8` (only index 3 contributes: `2*4`)
- `a = [0, 1, 0, 0, 2, 0, 0]`, `b = [1, 0, 0, 0, 3, 0, 4]` -> `6` (only index 4 contributes: `2*3`)
- `a = [1, 2, 3]`, `b = [4, 5, 6]` -> `32`
Element values and the resulting dot product fit in a signed 64-bit integer.
Constraints
- Both vectors have the same length n with 1 <= n <= 10^7.
- Element values fit in a signed 64-bit integer.
- The dot product is guaranteed to fit in a signed 64-bit integer.
Examples
Input: ([1, 0, 0, 2, 3], [0, 3, 0, 4, 0])
Expected Output: 8
Explanation: Only index 3 has both non-zero: 2*4 = 8.
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.
Input: ([1, 2, 3], [4, 5, 6])
Expected Output: 32
Explanation: 4 + 10 + 18 = 32.
Input: ([7], [-3])
Expected Output: -21
Explanation: Single-element vectors: 7*-3 = -21.
Input: ([-2, 3, -4], [4, -5, 6])
Expected Output: -47
Explanation: -8 + -15 + -24 = -47 (negatives).
Input: ([1000000], [1000000])
Expected Output: 1000000000000
Explanation: Large product still fits in 64-bit: 10^12.
Hints
- Walk both arrays together in a single pass, multiplying the aligned elements.
- Accumulate the running sum of a[i]*b[i]; you never need to store intermediate products.
Dot Product of Two Sparse Vectors
Follow-up to the dense version. In practice the vectors are **very long but mostly zeros** (for example length 10^7 with only a few hundred non-zero entries), so iterating every position wastes time and memory.
Each vector is given as a list of `[index, value]` pairs for its **non-zero** entries only, **sorted by index ascending**, together with the logical length `n`. Compute the dot product using only the stored non-zero entries, so the running time depends on the number of stored entries rather than on `n`.
**Representation example**: dense `[0, 5, 0, 0, 9]` (n = 5) is stored as `[[1, 5], [4, 9]]`.
**Examples**
- `a = [[1, 5], [4, 9]]`, `b = [[0, 2], [4, 3]]`, `n = 5` -> `27` (only index 4 overlaps: `9*3`)
- `a = [[0, 1], [2, 2]]`, `b = [[1, 4], [3, 5]]`, `n = 4` -> `0` (no shared non-zero index)
Aim for `O(k_a + k_b)` time and `O(1)` extra space via a two-pointer merge over the sorted index lists.
Constraints
- Both vectors have the same logical length n with 1 <= n <= 10^7.
- Within each vector, indices are distinct and sorted ascending, with 0 <= index < n.
- Element values and the dot product fit in a signed 64-bit integer.
- Target O(k_a + k_b) time and O(1) extra space (two-pointer merge).
Examples
Input: ([[1, 5], [4, 9]], [[0, 2], [4, 3]], 5)
Expected Output: 27
Explanation: Only index 4 overlaps: 9*3 = 27.
Input: ([[0, 1], [2, 2]], [[1, 4], [3, 5]], 4)
Expected Output: 0
Explanation: No shared non-zero index, so the product is 0.
Input: ([], [], 5)
Expected Output: 0
Explanation: Both vectors are all zeros; empty sparse lists give 0.
Input: ([[0, 3]], [[0, 4]], 1)
Expected Output: 12
Explanation: Single overlapping index 0: 3*4 = 12.
Input: ([[0, -2], [3, 5]], [[0, 4], [3, -1]], 5)
Expected Output: -13
Explanation: Indices 0 and 3 overlap: -2*4 + 5*-1 = -8 + -5 = -13.
Input: ([[2, 7]], [[0, 1], [1, 2], [3, 4]], 4)
Expected Output: 0
Explanation: Index 2 of a matches nothing in b; pointers never align on a shared index.
Hints
- Both index lists are already sorted, so you can merge them like the merge step of merge sort using two pointers.
- A product only contributes when the two current indices are equal; otherwise advance the pointer at the smaller index.
- When one pointer runs off the end, the remaining entries of the other vector have no counterpart and can be ignored.