从M个数中随机取出N个

简介:

看到这样一个题目:在M个数中,随机取出其中的N个,要求等概率。

这应该是一个比较简单的题目,看到题目后的第一想法是:维护一个关于这M个数的集合,然后每次随机从集合中抽一个数,抽N次即可。
等概率显然不是什么问题,当然前提是假设随机函数是等概率的,否则任何方法都免谈了。
对于其中的每一个数,它在每一次不被抽走的概率是:(M-1)/M、(M-2)/(M-1)、...、(M-N)/(M-N-1),到最后还没被抽走的概率就是(M-N)/M,也就是说它会被抽走的概率是N/M。

看到一个网友的解决思路,感觉很有意思:

在M个数中,随机取出其中的N个,那么每个数被选中的概率都是N/M。

对于其中的第一个数字,它被选中的概率是N/M,所以随机生成一个来自(0,1)之间的均匀分布的实数u。
如果u<N/M,则这个数被选中。于是问题简化为:对于剩下的M-1个数,等概率选择其中的N-1个,每个数被选中的概率都是(N-1)/(M-1);
否则,这个数字不被选中。问题简化为:对于剩下的M-1个数,等概率选择其中的N个,每个数被选中的概率都是N/(M-1);

简单分析一下概率:对于这第一个数字,它被选中的概率就是N/M。
对于剩下的M-1个数,任何一个数被选中的概率是: N/M * (N-1)/(M-1) + (1-N/M) * N/(M-1) = N/M. 因此满足题意。

这样的思路让人很受启发……


目录
相关文章
数组筛选,将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10元素选出来,放入新数组,声明一个新的数组用于存放新数据newArr,遍历原来的旧数组,找到大于10的元素,依次追加新数组
数组筛选,将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10元素选出来,放入新数组,声明一个新的数组用于存放新数据newArr,遍历原来的旧数组,找到大于10的元素,依次追加新数组
交换两个数的值的方法(三种)
交换两个数的值的方法(三种)
67 1
|
6月前
|
机器学习/深度学习 算法 数据处理
盘点四种计算数组中元素值为1的个数的方法
盘点四种计算数组中元素值为1的个数的方法
88 0
|
6月前
|
算法 测试技术 C#
【位运算 试填法】【推荐】3022. 给定操作次数内使剩余元素的或值最小
【位运算 试填法】【推荐】3022. 给定操作次数内使剩余元素的或值最小
|
6月前
1004.最大连续1的个数
1004.最大连续1的个数
30 0
|
6月前
|
人工智能
输入一个数,将它插入数组中
输入一个数,要求按原来的规律将它插入数组中。
79 2
|
存储 算法 JavaScript
设计并实现一个函数, 功能为给定一个存储为随机整数的数组,从中删除所有值为i的整数
设计并实现一个函数, 功能为给定一个存储为随机整数的数组,从中删除所有值为i的整数
|
算法 前端开发
【前端算法】最大连续1的个数,一次遍历
给定一个二进制数组, 计算其中最大连续1的个数。
121 0
【前端算法】最大连续1的个数,一次遍历
随机生成十个不重复的数组元素
随机生成十个不重复的数组元素
132 0
|
人工智能 算法 BI
给定一个数组,找出不在数组中的最小的那个数字
这是在TL讨论中Liu xinyu给出的一个例子,觉得思路挺有启发的,所以整理记录一下。 给定一个数组,其内容是一些随机的、不重复的正整数,如: {4, 23, 1, 8, 9, 21, 6, 12} 要求找出不在数组中出现的最小的那个数,比如这个数组中未在数组中出现的最小值是:2 这个问题实际应用的原型可以是一个ID分配系统,其使用一个数组来保存已分配的ID,每次回收就从数组中删除一个元素(O(n)),而分配则需要找到最小的那个可用的ID,就是这个算法要做的事情。
1082 0