赞
踩
题目链接:LCR 071. 按权重随机选择 - 力扣(LeetCode)
题目:
给定一个正整数数组 w,其中 w[i] 代表下标 i 的权重(下标从 0 开始),请写一个函数 pickIndex,它可以随机地获取下标 i,选取下标 i 的概率与 w[i] 成正比。
例如,对于 w = [1, 2, 3, 4],选取下标 0 的概率为 1 / (1 + 2 + 3 + 4) = 0.1(即 10%),选取下标 1 的概率为 2 / 10 = 0.2(即 20%),选取下标 3 的概率为 3 / 10 = 0.3(即 30%),选取下标 4 的概率为 4 / 10 = 0.4(即 40%)。
分析:
创建一个和权重数组 w 的长度一样的数组 sums,其中 sums[i] 是权重数组中前 i 个数字之和。例如,累加权重数组 [1, 2, 3, 4] 中的权重得到的数组 sums 为 [1, 3, 6, 10]。
有了这个累加权重的数组之后,等概率地生成 1 到 10 之间的一个随机数 p,如果 p <= 1,则选取下标 0;如果 1 < p <= 3,则选取下标 1;如果 3 < p <= 6,则选取下标 2;如果 6 < p <= 10,则选取下标 3。
也就是说,随机生成 p 之后,找到数组 sum 中第一个大于或等于 p 的值,然后选取它对应的下标。
代码实现:
- class Solution {
- public:
- Solution(vector<int>& w) {
- int n = w.size();
- sum.resize(n);
- sum[0] = w[0];
- for (int i = 1; i < n; ++i)
- {
- sum[i] = w[i] + sum[i - 1];
- }
- }
-
- int pickIndex() {
- int p = rand() % sum.back() + 1;
-
- int left = 0;
- int right = sum.size() - 1;
- while (left < right)
- {
- int mid = (left + right) / 2;
- if (sum[mid] < p)
- left = mid + 1;
- else // sum[mid] >= p
- right = mid;
- }
- return right;
- }
- private:
- vector<int> sum;
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。