diff --git a/leetcode/501-600/0528.Random-Pick-with-Weight/README.md b/leetcode/501-600/0528.Random-Pick-with-Weight/README.md index d2d5fa5b7..6b27ad731 100644 --- a/leetcode/501-600/0528.Random-Pick-with-Weight/README.md +++ b/leetcode/501-600/0528.Random-Pick-with-Weight/README.md @@ -1,28 +1,53 @@ # [528.Random Pick with Weight][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +You are given a **0-indexed** array of positive integers `w` where `w[i]` describes the **weight** of the `ith` index. + +You need to implement the function `pickIndex()`, which **randomly** picks an index in the range `[0, w.length - 1]` (**inclusive**) and returns it. The **probability** of picking an index i is `w[i] / sum(w)`. + +- For example, if `w = [1, 3]`, the probability of picking index `0` is `1 / (1 + 3) = 0.25` (i.e., `25%`), and the probability of picking index `1` is `3 / (1 + 3) = 0.75` (i.e., `75%`). **Example 1:** ``` -Input: a = "11", b = "1" -Output: "100" +Input +["Solution","pickIndex"] +[[[1]],[]] +Output +[null,0] + +Explanation +Solution solution = new Solution([1]); +solution.pickIndex(); // return 0. The only option is to return 0 since there is only one element in w. ``` -## 题意 -> ... +**Example 2:** -## 题解 - -### 思路1 -> ... -Random Pick with Weight -```go ``` - +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 is returning the second element (index = 1) that has a probability of 3/4. +solution.pickIndex(); // return 1 +solution.pickIndex(); // return 1 +solution.pickIndex(); // return 1 +solution.pickIndex(); // return 0. It is returning the first element (index = 0) that has a probability of 1/4. + +Since this is a randomization problem, multiple answers are allowed. +All of 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. +``` ## 结语 diff --git a/leetcode/501-600/0528.Random-Pick-with-Weight/Solution.go b/leetcode/501-600/0528.Random-Pick-with-Weight/Solution.go index d115ccf5e..4fab417cb 100644 --- a/leetcode/501-600/0528.Random-Pick-with-Weight/Solution.go +++ b/leetcode/501-600/0528.Random-Pick-with-Weight/Solution.go @@ -1,5 +1,46 @@ package Solution -func Solution(x bool) bool { - return x +import ( + "math/rand" + "sort" + "time" +) + +type Solution528 struct { + sum int + prefixSum []int + + r *rand.Rand +} + +func Constructor(w []int) Solution528 { + sum := 0 + + prefixSum := make([]int, len(w)) + for i := range w { + sum += w[i] + prefixSum[i] = sum + } + seed := rand.New(rand.NewSource(time.Now().UnixNano())) + return Solution528{ + sum: sum, + prefixSum: prefixSum, + r: seed, + } +} + +func (this *Solution528) PickIndex() int { + ret := this.r.Intn(this.sum) + return sort.Search(len(this.prefixSum), func(i int) bool { + return this.prefixSum[i] > ret + }) +} + +func Solution(w []int, n int) []int { + c := Constructor(w) + ret := make([]int, n) + for i := range n { + ret[i] = c.PickIndex() + } + return ret } diff --git a/leetcode/501-600/0528.Random-Pick-with-Weight/Solution_test.go b/leetcode/501-600/0528.Random-Pick-with-Weight/Solution_test.go index 14ff50eb4..a9e0d0e46 100644 --- a/leetcode/501-600/0528.Random-Pick-with-Weight/Solution_test.go +++ b/leetcode/501-600/0528.Random-Pick-with-Weight/Solution_test.go @@ -10,30 +10,29 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + w []int + n int + expect []int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", []int{1}, 1, []int{0}}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.w, c.n) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v", + c.expect, got, c.w, c.n) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }