[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. 按权重随机选择(前缀和+数学+概率+几何概型+好题)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 528 按权重随机选择[前缀和 二分法] HERODING的LeetCode之路

leetcode 528 按权重随机选择

[528]. 按权重随机选择

[528]. 按权重随机选择

按权重随机选择(leetcode 528)

按权重随机选择(leetcode 528)