Random Pick with Weight

Given an arraywof positive integers, wherew[i]describes the weight of indexi, write a functionpickIndex which randomly picks an index in proportion to its weight.

Note:

  1. 1 <= w.length <= 10000

  2. 1 <= w[i] <= 10^5

  3. pickIndex will be called at most10000times.

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 arrayw.pickIndexhas no arguments. Arguments are always wrapped with a list, even if there aren't any.

Analysis

用accumlated weight sum代表概率分布,每个区间就模拟了均匀分布的概率。比如

then get random val random.nextInt(14) + 1, idx is in range [1,14]

这样就转化为了search insert index。

这里要找的其实是大于target的最小的数的index。

Binary Search的方法见Search Insert Position:https://leetcode.com/problems/search-insert-position/submissions/

About java.util.Random: https://www.geeksforgeeks.org/java-util-random-nextint-java/

java.util.Random.nextInt(int n)

因此需要用到

random.nextInt(max) + 1将随机数取值范围从[0, max)变成[1, max];

Time: O(n)to init, O(logn)for one pick

Space: O(n)

Solution

Prefix Sum + Binary Search (Template#1)

Reference

https://leetcode.com/problems/random-pick-with-weight/discuss/154044/Java-accumulated-freq-sum-and-binary-search

http://www.cnblogs.com/grandyang/p/9784690.html

Weighted Random Distribution

Last updated

Was this helpful?