昨天面试字节,手写代码之后进一步考查了一道题。面试官让我说一下有什么思路。
题目如下:

有一个函数int getNum(),每运行一次可以从一个数组V[N]里面取出一个数,N未知,当数取完的时候,函数返回NULL。现在要求写一个函数int get(),这个函数运行一次可以从V[N]里随机取出一个数,而这个数必须是符合1/N平均分布的,也就是说V[N]里面任意一个数都有1/N的机会被取出,要求空间复杂度为O(1)。

我当时的思路是如果随机抽取,那么肯定要用到random方法,另外如果不能获得数组长度,那么取数过程中我能用到的数据只有:当前数字的值当前数字的索引。随后就看如何构建函数保证每个数字的被取出的概率相同即可。
不过具体如何构建函数,我没有想到。
结束后,我查询了一下相关的解析如下:

  1. 设置一个整形nVal,用来存放get()返回的数。
  2. 调用getNum()从V[N]取数,按一定概率存入nVal中(覆盖以前的),直到getNum()返回NULL。
  3. 设getNum取的第i个数为nVali,nVali存入nVal中的概率为Pi。 设Pi=1/i (i已知时,所以这个概率很容易做到)。
  4. 则nVali保留,并最后返回的情况是,nVali被存入num中,且nValj(i<j<=N)不被存入nVal。
    其概率为

P(nVali)=Pi*(1- Pi+1) * (1 - Pi+2)* …(1 - PN)
=1/i * (i/(i+1)) ((i+1)/(i+20)…((N-1)/N) = 1/N

由于我们这里无法获得N的长度,所以我们可以用生成的随机数对当前索引i取余数,来保证结果的随机性(其实我这里并不是特别的理解)。改写成对应C++的代码如下

int GetRand()
{int i=1;int nRet = 0;int nVal = 0;while((nRet=getNum())!=NULL){if(rand()%(i++)==0) nVal = nRet;}return nVal;
}

由于我的主语言是Python,所以我尝试把这段代码改写成Python。比较尴尬的一点是,Python中的随机数只能在某一个范围内生成(即不可能生成一个无限大的数字)。这样,我们需要构建一个新的字符来统计当前出现过的最大值。这样我写出的代码如下:

nums = [2,3,1,4,5,6,8,7,9]import random
i = 1
val = 0
Max = 0
while nums:n = nums.pop()#统计当前数组中出现的最大值Max = max(n,Max)if random.randint(0,Max) % i == 0:val = ni += 1print(val)

如此就可以实现上述功能啦!

随机从长度未知的数组中抽取数字,且保证每个元素被抽到的概率相同相关推荐

  1. 【宫水三叶的刷题日记】961. 在长度 2N 的数组中找出重复 N 次的元素

    题目描述 这是 LeetCode 上的 961. 在长度 2N 的数组中找出重复 N 次的元素 ,难度为 简单. Tag : 「模拟」.「计数」.「构造」.「哈希表」 给你一个整数数组 nums ,该 ...

  2. java中数组的下标比较_【Java】 剑指offer(53-3) 数组中数值和下标相等的元素

    本文参考自<剑指offer>一书,代码采用Java语言. 题目 假设一个单调递增的数组里的每个元素都是整数并且是唯一的.请编程实现一个函数找出数组中任意一个数值等于其下标的元素.例如,在数 ...

  3. 215. 数组中的第 K个最大元素

    215. 数组中的第 K个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数 组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...

  4. LC215. 数组中的第K个最大元素

    题目介绍 数组中的第K个最大元素 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素. 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 输入: [ ...

  5. 对数组中的数字 1 和 2 进行排序,使得数字 1、2 分别位于前、后部分

    问题描述:假设某个数组中只有数字 1 和 2,进行排序,使得数字 1 位于数组前部分,数字 2 位于后部分. 这道算法题其实不是很难,使用各种排序算法应该都能解出,但是若要考虑性能问题,那就得选择一种 ...

  6. 数组中的第K个最大元素

    数组中的第K个最大元素 在未排序的数组中找到第k个最大的元素.请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素. 示例 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...

  7. LeetCode——215,数组中的第K个最大元素(分治法)

    尹成老师带你学算法 /*** \* Created: liuhuichao* \* Date: 2020/1/27* \* Time: 11:32 上午* \* Description: 数组中的第K ...

  8. 力扣(LeetCode)215. 数组中的第K个最大元素(C语言)

    一.环境说明 本文是 LeetCode 215题 : 数组中的第K个最大元素,使用c语言实现. 快速选择.查找无序数组的利器! 测试环境:Visual Studio 2019. 二.代码展示 void ...

  9. 【Dart 教程系列第 6 篇】Dart 之 addAll 合并两个数组(向数组中一次添加多个元素)

    这是[Dart 教程系列第 6 篇],如果觉得有用的话,欢迎关注专栏. Dart 合并两个数组,或者说是向数组中一次添加多个元素,可以使用 addAll() 方法. 该方法无返回值,参数类型为 Ite ...

最新文章

  1. AngularJS ng-if使用
  2. 血亏 1.5 亿、华为断供、Linux 之父怒删代码,2020 IT 大事记盘点
  3. vs2010 失效后的解决办法
  4. Linux文件目录及其作用
  5. Redis中的客户端重定向
  6. Intellij idea 快键键
  7. 面试官系统精讲Java源码及大厂真题 - 01 开篇词:为什么学习本专栏
  8. Android中文API(128) —— HandlerThread
  9. mysql的事务与锁机制
  10. Bootstrap3 Affix插件
  11. android 解压zip报错_Android 使用 Batterystats 和 Battery Historian 分析电池用量
  12. sql查询条件为空的另类写法o( ̄▽ ̄)d
  13. flex-direction css3属性设定弹性盒子模型子元素反向排列
  14. 深度学习: marginal cost (边际成本)
  15. 安卓从入门到进阶第一篇(环境搭建)
  16. ABAP 企业微信ASE 加密算法
  17. 一种自动将3DMax模型转换为UE4直接可用的模型资源的方法与流程
  18. Vue路由守卫(导航守卫)及使用场景
  19. Android动画了解—一些项目案例分析
  20. iOS15上最受欢迎的功能,居然是“我想静静”?

热门文章

  1. autojs安卓10,11泡椒云提示无法读取imei码解决方案
  2. 单目三维目标检测之CaDDN论文阅读
  3. 12枚硬币中取1枚假币的问题
  4. 画风突变!用友云全新定义数字企业智能服务
  5. php网页无痕预览,javascript,html5_如何应对用户使用无痕浏览模式,javascript,html5 - phpStudy...
  6. 计算机中所说的云是什么意思,如何理解云计算中的“云”是什么?
  7. linux命令行怎么播放,在linux命令行里能听歌看电影吗
  8. Google Earth Engine(python)——Sentinel 2 影像的地形、坡度、坡向和太阳高度角校正
  9. R软件--GEO数据分析教程:差异性分析、富集分析(GO\KEGG\DO)
  10. 2022年全国PMP考试地点汇总,你都知道吗?