Description
Given an array w of positive integers, where w[i] describes the weight of index i, write a function pickIndex which randomly picks an index in proportion to its weight.
Note:
1 <= w.length <= 10000
1 <= w[i] <= 10^5
pickIndex will be called at most 10000 times.
Example 1:
Input:
[“Solution”,“pickIndex”]
[[[1]],[]]
Output: [null,0]
Example 2:
Input:
[“Solution”,“pickIndex”,“pickIndex”,“pickIndex”,“pickIndex”,“pickIndex”]
[[[1,3]],[],[],[],[],[]]
Output: [null,0,1,1,1,0]
Explanation of Input Syntax:
The input is two lists: the subroutines called and their arguments. Solution’s constructor has one argument, the array w. pickIndex has no arguments. Arguments are always wrapped with a list, even if there aren’t any.
Solution
设计一个储存数据结构,传入一个表明了index群众的数组w,要求能够根据权重随机返回对应的index。
We create a new int array which stores the sum of before weights. So get a index randomly according to weight is converted to binary search a sum value in a sorted array. Random could generate a value between 1 to sum. Find the random value in sum[] find the index would be fine.
Code
class Solution {
int[] sum;
Random rand;
public Solution(int[] w) {
this.rand = new Random();
for (int i = 1; i < w.length; i++){
w[i] += w[i - 1];
}
this.sum = w;
}
public int pickIndex() {
int value = rand.nextInt(sum[sum.length - 1]) + 1;
int left = 0, right = sum.length - 1;
while (left < right){
int mid = (left + right) / 2;
if (sum[mid] == value){
return mid;
}
else if (sum[mid] > value){
right = mid;
}
else{
left = mid + 1;
}
}
return left;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(w);
* int param_1 = obj.pickIndex();
*/
Time Complexity: O(nlogw)
Space Complexity: O(w)