[M数学] lc528. 按权重随机选择(前缀和+数学+概率+几何概型+好题)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M数学] lc528. 按权重随机选择(前缀和+数学+概率+几何概型+好题)相关的知识,希望对你有一定的参考价值。
1. 题目来源
链接:528. 按权重随机选择
2. 题目解析
一般来讲,产生随机数本身就是一个不可靠的事情。但是本题对于工程上而言,也是有一定实际意义的。例如,负载均衡,算力各不相同当然要以不同的权重进行分配。但是前面讲了,因为随机数的不稳定性,又产生新的算法,一致性哈希等。
本题,其实可以将其理解为一个几何概型。w[i]
为在数轴上的长度,在总长度 sum
中进行随机的投针试验,落到那一段和其长度成正比,也是符合其题目要求的。抽象如下图:
但是实际上,我们并不需要真的随机一个小数,然后判断其再哪一段。我们可以将其再离散化,将点 {1}
作为下标 0 的一段,点 {2, 3}
作为下标 1 的一段,点 {4,5,6}
作为下标 2 的一段。
这些段的分界点恰好就是对应左边的前缀和,只需要随机 {1,2,3,4,5,6}
这些随机数(也就是 [1,sum]
之间的整数),也可以按照概率将其分到每一段。
具体来讲,如果随机到 x
,我们只需找到大于等于 x
的那个数在哪一段即可。例如,x=4
,那么大于等于 4 的第一个区间段就是下标为 2 的这一段,且前缀和数组 s[0]=1,s[1]=3,s[2]=6
。刚好就停在下标为 2 的位置处,也就完成了一次从值到下标的随机查找。
这个设计很巧妙,先是转化为几何概型,然后再将其转为整数问题,再结合前缀和+二分的思想优化解题。很不错。
稠密的长度,可以转化为稀疏的整数。只要倍数关系不变,概率整体就不变。
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度: O ( n ) O(n) O(n)
class Solution {
public:
vector<int> s;
Solution(vector<int>& w) {
s = w;
for (int i = 1; i < s.size(); i ++ ) s[i] += s[i - 1];
}
int pickIndex() {
int x = rand() % s.back() + 1; // 取得 [1, sum] 中的整数部分随机数
return lower_bound(s.begin(), s.end(), x) - s.begin();
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(w);
* int param_1 = obj->pickIndex();
*/
以上是关于[M数学] lc528. 按权重随机选择(前缀和+数学+概率+几何概型+好题)的主要内容,如果未能解决你的问题,请参考以下文章