与这一题类似:LeetCode第 382 题:链表随机节点(C++)_zj-CSDN博客,蓄水池抽样问题。
蓄水池抽样——《编程珠玑》读书笔记_Stay hungry, Stay foolish-CSDN博客
先选择第一个对象,然后以1/2的概率选择第二个对象(如果选择了第二个对象,第一个自然就舍弃了),再以1/3的概率选择第三个对象…以此类推,以1/m的概率选择第m个对象。最后选择过程结束时,每一个对象被选中的概率就是 1/n(n为对象总数)。
这一题里面应该是不太可能保存一个输入数组的拷贝作为成员变量的,所以可以使用指针保存相应的地址。
class Solution {
public:
Solution(vector<int>& nums) : a(nums){}//引用的初始化只能在初始值列表里
int pick(int target) {
int cnt = 1, res = 0, n = a.size();//cnt为计数器
for(int i = 0; i < n; ++i){
if(a[i] == target){
if(rand()%cnt == 0) res = i;//以1/cnt的概率选择该元素
++cnt;
}
}
return res;
}
private:
vector<int>& a;
};