Random Pick with Weight - Codeprg

Breaking

programing News Travel Computer Engineering Science Blogging Earning

Monday 17 August 2020

Random Pick with Weight

Random Pick with Weight


 Random Pick with Weight



Given an array of positive integers w. where w[i] describes the weight of ith index (0-indexed).

We need to call the function pickIndex() which randomly returns an integer in the range [0, w.length - 1]pickIndex() should return the integer proportional to its weight in the w array. For example, for w = [1, 3], the probability of picking index 0 is 1 / (1 + 3) = 0.25 (i.e 25%) while the probability of picking index 1 is 3 / (1 + 3) = 0.75 (i.e 75%).

More formally, the probability of picking index 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 single element on the array the only option is to return the first element.

Example 2:



Input
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output
[null,1,1,1,1,0]

Explanation
Solution solution = new Solution([1, 3]);
solution.pickIndex(); // return 1. It's returning the second element (index = 1) that has probability of 3/4.
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 1
solution.pickIndex(); // return 0. It's returning the first element (index = 0) that has probability of 1/4.

Since this is a randomization problem, multiple answers are allowed so 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.
class Solution {
private:
    vector<int> v;
    int s;
public:
    Solution(vector<int>& w) {
        v.push_back(w[0]);
        for(int i=1;i<w.size();++i)
            v.push_back(w[i]+v.back());
        s=w.size();
    }
    
    int pickIndex() {
        int i=(rand()%v[s-1])+1;
        int l=0,r=s-1;
        while(l<r)
        {
            int mid=(r+l)/2;
            if(v[mid]==i)
                return mid;
            else if(v[mid]<i)
                l=mid+1;
            else
                r=mid;
        }
        return l;
    }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(w);
 * int param_1 = obj->pickIndex();
 */