LeetCode: Random Pick with Weight Posted on August 5, 2019July 26, 2020 by braindenny Random Pick with Weight Similar Problems: CheatSheet: Leetcode For Code Interview CheatSheet: Common Code Problems & Follow-ups Tag: #presum, #binarysearch, #random 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. Github: code.dennyzhang.com Credits To: leetcode.com Leave me comments, if you have better ways to solve. Solution: // https://code.dennyzhang.com/random-pick-with-weight // Basic Ideas: presum + binarysearch // // Complexity: Time O(log(n)), Space O(n) import "math/rand" type Solution struct { presums []int } func Constructor(w []int) Solution { presums := make([]int, len(w)) sum := 0 for i, v := range w { sum += v presums[i] = sum } return Solution{presums:presums} } func (this *Solution) PickIndex() int { target := rand.Intn(this.presums[len(this.presums)-1])+1 left, right := 0, len(this.presums) // result must exist in the list for left < right { mid := (right-left)/2+left if this.presums[mid] < target { // search right half left = mid+1 } else { right = mid } } return left } /** * Your Solution object will be instantiated and called as such: * obj := Constructor(w); * param_1 := obj.PickIndex(); */ Post Views: 0