Source: https://leetcode.com/problems/random-pick-with-weight/

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). For example, if 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%).

/**
* @param {number[]} w
*/
// O(W) where W is the total weight as we form an index slots array with W slots filled with the index numbers
var Solution = function(w) {
// Get the sum of the array weights i.e. [1,3] = 1 + 3 = 4
this.totalWeight = w.reduce((acc, current) => acc + current, 0);
// Given an array like [1,3], we will form another array like [0,1,1,1] to represent the weight distribution of indices
this.indexSlots = [];
let currentIndex = 0;
for (let i = 0; i < w.length; i++) {
const numCurrentIndex = w[i];
// Push the current index the number of times it should appear in the index slots to represent the probability
// i.e. one 0, three 1 index
for (let j = 0; j < numCurrentIndex; j++) {
this.indexSlots.push(currentIndex);
}
currentIndex++;
}
};
/**
* @return {number}
*/
Solution.prototype.pickIndex = function() {
const randomIndex = Math.floor(Math.random() * this.totalWeight);
return this.indexSlots[randomIndex];
};
/**
* Your Solution object will be instantiated and called as such:
* var obj = new Solution(w)
* var param_1 = obj.pickIndex()
*/