website/content.en/ChapterFour/0500~0599/0528.Random-Pick-with-Weight.md
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 <= 100001 <= w[i] <= 10^5pickIndex 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.
Given a positive integer array w, where w[i] represents the weight of position i, write a function pickIndex that can randomly get position i, where the probability of selecting position i is proportional to w[i].
Note:
Explanation of input syntax:
The input consists of two lists: the names of the member functions called and the parameters for the calls. The constructor of Solution has one parameter, which is the array w. pickIndex has no parameters. The input parameters are a list; even if the parameters are empty, an empty list [] will be input.
pickIndex() randomly picks a position i, and the probability of this position appearing is proportional to that element value.x in the interval [0,prefixSum). The index i is the smallest index satisfying the condition x< prefixSum[i]; finding this index i is the final answer. Use binary search to find the index i. For some index i, all integers v satisfying prefixSum[i] - w[i] ≤ v < prefixSum[i] map to this index. Therefore, all indices are proportional to their index weights.pickIndex() is O(log n). Space complexity is O(n).
package leetcode
import (
"math/rand"
)
// Solution528 define
type Solution528 struct {
prefixSum []int
}
// Constructor528 define
func Constructor528(w []int) Solution528 {
prefixSum := make([]int, len(w))
for i, e := range w {
if i == 0 {
prefixSum[i] = e
continue
}
prefixSum[i] = prefixSum[i-1] + e
}
return Solution528{prefixSum: prefixSum}
}
// PickIndex define
func (so *Solution528) PickIndex() int {
n := rand.Intn(so.prefixSum[len(so.prefixSum)-1]) + 1
low, high := 0, len(so.prefixSum)-1
for low < high {
mid := low + (high-low)>>1
if so.prefixSum[mid] == n {
return mid
} else if so.prefixSum[mid] < n {
low = mid + 1
} else {
high = mid
}
}
return low
}
/**
* Your Solution object will be instantiated and called as such:
* obj := Constructor(w);
* param_1 := obj.PickIndex();
*/