You are given a 0-indexed array of positive integers w where w[i] describes the weight of the ith index.
You need to implement the function pickIndex(), which randomly picks an index in the range [0, w.length - 1] (inclusive) and returns it. The probability of picking an index i is w[i] / sum(w).
w = [1, 3], the probability of picking index 0 is 1 / (1 + 3) = 0.25 (i.e., 25%), and the probability of picking index 1 is 3 / (1 + 3) = 0.75 (i.e., 75%).Input
["Solution","pickIndex"]
[[[1]],[]]
Output
[null,0]
Explanation
Input
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output
[null,1,1,1,1,0]
Explanation
Since this is a randomization problem, multiple answers are allowed.
All of the following outputs can be considered correct:
[null,1,1,1,1,0]
[null,1,1,1,1,1]
[null,1,1,1,0,0]
[null,1,1,1,0,1]
[null,1,0,1,0,0]
......and so on.
pickIndex will be called at most 104 times.The main goal is to pick an index i with a probability proportional to w[i]. If we imagine each weight as a segment on a line of length sum(weights), then we can pick a random point on this line and determine which segment it falls into using binary search. Thus, the problem boils down to constructing a prefix sum array and using binary search to determine our pick.
This approach uses a dynamic data structure like a balanced binary search tree (e.g., TreeMap in Java) to store cumulative weights, allowing for efficient cumulative lookup and random access. This is especially efficient if weights frequently update or if the number of weights (N) is very large.
TreeMap, where each key is a cumulative weight, and the value is the corresponding index.pickIndex call, randomly determine a target and find the smallest key in the map greater or equal to the target.TreeMap is logarithmic on average.TreeMap.