题目链接:点击查看
题目描述:
给定一个数组,数组每个位置的值表示该位置的权重,要求按照权重的概率去随机采样。
输入输出:
输入:
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex" ]
[ [ [1,3] ],[ ],[ ],[ ],[ ],[ ] ]
输出:
[null,1,1,1,1,0]
输入:
["Solution","pickIndex"]
[ [ [1] ],[ ] ]
输出:
[ null,0 ]
题目分析:
我们可以先使用
partial_sum
求前缀和(即到每个位置为止之前所有数字的和),这个结果对于正整数数组是单调递增的。每当需要采样时,我们可以先随机产生一个数字,然后使用二分法查找其在前缀和中的位置,以模拟加权采样的过程。这里的二分法可以用 lower_bound
实现。例如,样例二 权重数组[1,3]
的前缀和为
[1,4]
。如果我们随机生成的数字为
1
,那么
lower_bound返回的位置为 0
;如果我们随机生成的数字是
2
、
3
、
4
,那么
lower_bound
返回的位置为
1
。
代码:
class Solution
{
vector<int>sums;
public:
Solution(vector <int> weights) :sums(std::move(weights))
{
partial_sum(sums.begin(),sums.end(),sums.begin()); //partial_sum 是C++ STL 算法组件中的其中一个算法,其作用是计算某个序列局部元素的和
} //partial_sum(容器要计算的起始位置,容器要计算的结束位置,结果存放的起始位置)
int pickIndex()
{
int pos=(rand()%sums.back()+1);
return lower_bound(sums.begin(),sums.end(),pos)-sums.begin();
}
};