leetcode 528 按权重生成随机数

16 篇文章 0 订阅
class Solution {
private:
    mt19937 gen;
    uniform_int_distribution<int> dis;
    vector<int> pre;

public:
    Solution(vector<int>& w): gen(random_device{}()), dis(1, accumulate(w.begin(), w.end(), 0)) {
        partial_sum(w.begin(), w.end(), back_inserter(pre));
    }
    
    int pickIndex() {
        int x = dis(gen);
        return lower_bound(pre.begin(), pre.end(), x) - pre.begin();
    }
};

Solutin的构造函数后面加了一个冒号表示初始化列表,对成员进行初始化
首先这个程序需要产生均匀分布的随机数
C++将随机数分成了产生器和分布器
产生器为mt19937,通过给他一个种子就可以产生一个伪随机数,在这里这个种子是random_device{}(),一个随机的种子
然后分布器是uniform_int_distribution dis;,这说明是均匀分布
有3个参数,第一个参数1,表示均匀分布的下界,第二个参数accumulate(w.begin(), w.end(), 0)表示,w数组的和,accumulate中的0表示sum从0开始加。
partial_sum表示求w.begin到w.end的前缀和,back_insert(pre)表示会用push_back的方式加入到pre中
x=dis(gen)就产生了一个符号要求的随机数
lower_bound为二分查找第一个大于等于x的数
算法可以这样理解。我们维护两个界限,分别为:

        L:保证 ≤ L 位置的元素都小于 t;
        R:保证 ≥ R 位置的元素都大于等于 t。

   我们不断改变 L 和 R 的位置,使 L 和 R 不断靠近,直至 L + 1 = R 时,R 即为我们要查找的目标位置。

   假想 lo-1 位置存放着一个 -∞ 的哨兵,hi 位置存放着一个 +∞ 的哨兵。初始时 L = lo - 1, R = hi。

   如何调整 L 和 R 的位置呢?每次观察区间 [L, R] 中间位置的元素,即 A[mid = (L+R)/2] 的元素与 t 的大小,因为 A 的有序性:  

        若 A[mid] ≥ t, 我们可以把 R 替换为 mid。
        若 A[mid] < t,我们可以把 L 替换为 mid。
   这样,L 和 R 不断靠近,直至 L + 1 == R,则结束,R 则为我们要找的目标位置。

   C++代码示例(设要查找的类型是整数):

,-pre.begin表示返回的是下标

https://www.cnblogs.com/fyqq0403/p/10577827.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值