Implement weighted random index picker
Company: Meta
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: Implement weighted random index picker evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Constraints
- 1 <= weights.length <= 10^5
- 1 <= weights[i] (all weights are positive integers)
- Each target is a 1-based integer in [1, sum(weights)]
- 0 <= targets.length <= 10^7 picks
- sum(weights) fits in a 64-bit integer
Examples
Input: ([1], [1])
Expected Output: [0]
Explanation: One weight owns the whole range [1,1]; every draw returns index 0.
Input: ([1, 3], [1, 2, 3, 4])
Expected Output: [0, 1, 1, 1]
Explanation: Prefix sums [1,4]. Draw 1 -> index 0; draws 2,3,4 fall in (1,4] -> index 1. Index 1 is picked 3/4 of the time, matching weight 3 vs 1.
Input: ([5, 2, 3], [1, 5, 6, 7, 8, 9, 10])
Expected Output: [0, 0, 1, 1, 2, 2, 2]
Explanation: Prefix sums [5,7,10]. Draws 1-5 -> index 0; 6-7 -> index 1; 8-10 -> index 2 (widths 5,2,3 = the weights).
Input: ([2, 2, 2, 2], [1, 2, 3, 4, 5, 6, 7, 8])
Expected Output: [0, 0, 1, 1, 2, 2, 3, 3]
Explanation: Uniform weights: each index owns exactly 2 consecutive draw values.
Input: ([10], [1, 5, 10])
Expected Output: [0, 0, 0]
Explanation: Single large weight; all boundary draws (1, middle, max) return index 0.
Input: ([4, 1, 1, 1, 1], [4, 5, 6, 7, 8])
Expected Output: [0, 1, 2, 3, 4]
Explanation: Prefix sums [4,5,6,7,8]. Each listed draw is the exact upper boundary of an index's range, exercising the lower-bound (>=) tie behavior at every cut point.
Hints
- Precompute cumulative prefix sums: prefix[i] = weights[0] + ... + weights[i]. Index i 'owns' the half-open range (prefix[i-1], prefix[i]] of width weights[i].
- For a draw 'target', you want the first index whose prefix sum is >= target. That is a classic lower-bound binary search.
- Be careful with the binary-search invariant: use lo<hi with hi=mid (not mid-1) when prefix[mid] >= target, so you converge on the first qualifying index rather than overshooting.
- Extension: to support addWeight(i, delta) with sublinear updates, replace the static prefix array with a Fenwick tree (BIT) — both the point update and the prefix-sum binary search become O(log n).