《LeetCode之每日一题》:135.按权重随机选择
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:135.按权重随机选择相关的知识,希望对你有一定的参考价值。
题目链接: 按权重随机选择
有关题目
给定一个正整数数组 w ,
其中 w[i] 代表下标 i 的权重(下标从 0 开始),
请写一个函数 pickIndex ,
它可以随机地获取下标 i,
选取下标 i 的概率与 w[i] 成正比。
例如,对于 w = [1, 3],
挑选下标 0 的概率为 1 / (1 + 3) = 0.25 (即,25%),
而选取下标 1 的概率为 3 / (1 + 3) = 0.75(即,75%)。
也就是说,选取下标 i 的概率为 w[i] / sum(w) 。
示例 1:
输入:
["Solution","pickIndex"]
[[[1]],[]]
输出:
[null,0]
解释:
Solution solution = new Solution([1]);
solution.pickIndex(); // 返回 0,因为数组中只有一个元素,所以唯一的选择是返回下标 0。
示例 2:
输入:
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
输出:
[null,1,1,1,1,0]
解释:
Solution solution = new Solution([1, 3]);
solution.pickIndex(); // 返回 1,返回下标 1,返回该下标概率为 3/4 。
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 1
solution.pickIndex(); // 返回 0,返回下标 0,返回该下标概率为 1/4 。
由于这是一个随机问题,允许多个答案,因此下列输出都可以被认为是正确的:
[null,1,1,1,1,0]
[null,1,1,1,1,1]
[null,1,1,1,0,0]
[null,1,1,1,0,1]
[null,1,0,1,0,0]
......
诸若此类。
提示:
1 <= w.length <= 10000
1 <= w[i] <= 10^5
pickIndex 将被调用不超过 10000 次
题解
Tips
参考官方题解下烂柯人
C++STL说明:
1. mt19937头文件是<random> 是伪随机数产生器,用于产生高性能的随机数
2. uniform_int_distribution 头文件在<random>中,是一个随机数分布类,参数为生成随机数的类型,构造函数接受两个值表示区间段
3. accumulate 头文件在<numeric>中,求特定范围内所有元素的和。
4. partial_sum函数的头文件在<numeric>,对(first, last)内的元素逐个求累计和,放在result容器内
5. back_inserter函数头文件<iterator>,用于在末尾插入元素。
6. lower_bound头文件在<algorithm>,用于找出范围内不小于num的第一个元素
7. random_device生成真随机数
真随机数和伪随机数
法一:前缀和 + 二分查找
思路见官方题解
C++
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();
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(w);
* int param_1 = obj->pickIndex();
*/
C
typedef struct {
int* pre;
int preSize;
int total;
} Solution;
Solution* solutionCreate(int* w, int wSize) {
Solution* obj = (Solution*)malloc(sizeof(Solution));
obj->pre = (int*)malloc(sizeof(int) * wSize);
obj->preSize = wSize;
obj->total = 0;
for (int i = 0; i < wSize; ++i){
obj->total += w[i];
if (i > 0){
obj->pre[i] = obj->pre[i - 1] + w[i];
}
else {
obj->pre[i] = w[i];
}
}
return obj;
}
int binarySearch(Solution* obj, int target){
int l = 0, r = obj->preSize - 1;
while(l < r){
int mid = l + r >> 1;
if (obj->pre[mid] < target){
l = mid + 1;
}
else {
r = mid;
}
}
return l;
}
int solutionPickIndex(Solution* obj) {
int x = rand() % obj->total + 1;
return binarySearch(obj, x);
}
void solutionFree(Solution* obj) {
free(obj->pre);
free(obj);
}
/**
* Your Solution struct will be instantiated and called as such:
* Solution* obj = solutionCreate(w, wSize);
* int param_1 = solutionPickIndex(obj);
* solutionFree(obj);
*/
以上是关于《LeetCode之每日一题》:135.按权重随机选择的主要内容,如果未能解决你的问题,请参考以下文章