This is a question of the day from LeetCode 2021-8-30: “528. Randomly selected by weight”

1. Topic description

Given an array of positive integers w, where w[I] represents the weight of subscript I (subscripts start at 0), write a function pickIndex that randomly picks subscript I with a probability that is proportional to w[I].

For example, for w = [1, 3], the probability of choosing subscript 0 is 1 / (1 + 3) = 0.25 (i.e., 25%), while the probability of choosing subscript 1 is 3 / (1 + 3) = 0.75 (i.e., 75%).

In other words, the probability of picking subscript I is w[I] / sum(w).

Example 1:

Input: ["Solution","pickIndex"] [[[1]] output: [null,0] explanation: Solution Solution = new Solution([1]); solution.pickIndex(); // Return 0, since there is only one element in the array, the only option is to return the index 0.Copy the code

Example 2:

Input: [" Solution ", "pickIndex", "pickIndex", "pickIndex", "pickIndex", "pickIndex"] [[[1, 3]], [], [], [], [], []] output: [null,1,1,1,1,0] [null,1,1,1, 0] solution.pickIndex(); // Returns 1, returns subscript 1 with probability 3/4. solution.pickIndex(); // Return 1 solution.pickindex (); // Return 1 solution.pickindex (); // Return 1 solution.pickindex (); // Returns 0, returns subscript 0 with probability 1/4. Since this is a random question, allowing for multiple answers, the following output 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]... So on.Copy the code

2. Answer

Input array for [1, 2, 3, 4], for example, is divided into: [1, 1], [2, 3], [4 and 6], [7,8,9,10], calculate the prefix and array,3,6,10 [1].

Generates a random integer between [1,10], uses binary lookup to find the minimum subscript I in the prefix and array that satisfies the interval condition, and returns.

class Solution {
    constructor(w) {
        this.len = w.length;
        // Define prefixes and arrays
        this.pre = new Array(this.len).fill(0);
        this.pre[0] = w[0];
        // Start with I =1 and find the prefix sum for each position
        for (let i = 1; i < this.len; i++) {
            this.pre[i] = this.pre[i - 1] + w[i];
        }
        console.log(this.pre);
        / / the sum
        this.total = this.pre[this.len - 1];
    }
    pickIndex() {
        Math.random() returns a random number between 0 and 1
        // x is a random integer between 1 and total
        const x = Math.floor(Math.random() * this.total) + 1;
        // Binary search
        let [low, high] = [0.this.len - 1];
        while (low <= high) {
            const mid = (low + high) >> 1;
            if (this.pre[mid] < x) low = mid + 1;
            else high = mid - 1;
        }
        returnlow; }}Copy the code

😄 has recently created an open source repository to summarize LeetCode’s daily problems. It is currently available in C++ and JavaScript, and you are welcome to provide other language versions!

🖥️ Warehouse address: “One of the Day series”