Design compressed vector and compute dot product
GoogleSoftware Engineer · OnsiteLast updated
This problem tests your ability to design a memory-efficient data structure for sparse or repetitive vector data and implement an arithmetic operation without fully decompressing the representation.
Compressed Vector Dot Product
Many real-world vectors are sparse or contain long sequences of identical values. Instead of storing a full array of size N, we can represent a vector as a list of pairs (value, count), where count is the number of times value repeats consecutively.
Task
Design a class CompressedVector that stores a vector in this format. Then, implement a method dot_product(vec1, vec2) that computes the dot product of two CompressedVector objects.
Interface
class CompressedVector:
def __init__(self, data: list[tuple[int, int]]):
# data is a list of (value, count) pairs
self.data = data
def dot_product(vec1: CompressedVector, vec2: CompressedVector) -> int:
# Returns the dot product of the two vectors
Constraints
- Each vector may contain up to 10^6 elements, but the number of (value, count) pairs is significantly smaller (e.g., 10^3).
- Values are integers.
- Ensure your solution handles cases where the runs in
vec1andvec2have different boundaries.
Examples
Example 1:
vec1:[(1, 2), (3, 1)](represents[1, 1, 3])vec2:[(2, 1), (1, 2)](represents[2, 1, 1])Result:(1*2) + (1*1) + (3*1) = 6
Example 2:
vec1:[(5, 10)](represents 10 fives)vec2:[(2, 5), (3, 5)](represents 5 twos followed by 5 threes)Result:(5*2)*5 + (5*3)*5 = 50 + 75 = 125
Hints
Hint 1
Use two pointers to traverse the runs of both vectors simultaneously, keeping track of the current position or remaining count in each run.
Hint 2
In each step of the iteration, identify the 'min' of the remaining counts of the current runs to process a overlapping segment of length `k`.
Hint 3
Multiply the two current values and multiply by the overlapping segment length `k`, then update the remaining counts and move to the next run if a count hits zero.
Follow-up questions
- How would you modify the data structure if you needed to support efficient random access (e.g., get element at index i)?
- What is the time complexity of your dot product algorithm in terms of the number of compressed segments (M and K) rather than the original vector length (N)?
- How would you handle potential integer overflows if the dot product exceeds the capacity of a 32-bit integer?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.