leetcode 528. 按权重随机选择
给你一个下标从 0 开始 的正整数数组 w,其中 w[i] 代表第 i 个下标的权重。
请你实现一个函数 pickIndex,它可以随机地从范围 [0, w.length - 1] 内(含 0 和
w.length - 1)选出并返回一个下标。选取下标 i 的概率 为 w[i] / sum(w) 。例如,对于 w = [1, 3],挑选下标 0 的概率为 1 / (1 + 3) = 0.25(即,25%),而选取下标 1 的概率为 3 / (1 + 3) = 0.75(即,75%)。
rand()
Generate random number
Returns a pseudo-random integral number in the range between 0 and RAND_MAX.rand() % n 产生范围为
[0, n)
中的随机数。
举例分析
假设给定数组w=[1, 2, 3]。挑选下标0的概率为 1/(1+2+3)=1/6,而选取下标1的概率为2/(1+2+3)=2/6,选取下标2的概率为3/6。
使用线段长度表示下标0、1和2出现的概率,如下图所示:
(0, 6]区间总长为6,那么取(0, 6]范围内的随机数,该随机数落在(0,1]、(1,3]和(3,6]区间内的概率分别为1/6、2/6和3/6,即满足权值概率要求。
其中,区间分段点1、3、6即为前缀和
。
此处我们可以仅考虑随机数为整数的情况:(0, 6]区间内随机数为1属于(0,1];2、3属于(1,3];4、5、6属于(3,6]。
随机产生一个数字,然后使用二分法查找>=该数的最小值在前缀和中的位置
,即为下标。
代码
class Solution {
public:
vector<int> s;
Solution(vector<int>& w) {
s = w;
int n = w.size();
for (int i = 1; i < n; i++) s[i] += s[i - 1];
}
int pickIndex() {
int x = rand() % s.back() + 1; // 随机数范围[1...s.back()]
return lower_bound(s.begin(), s.end(), x) - s.begin();
}
};
应用场景
彩票调度算法[操作系统]
https://pages.cs.wisc.edu/~re...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。