忘我之乘积;及蓄水池抽样精妙解法

开发 项目管理
给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1]*A[2]*...*A[n]/A[i]。你不能使用除法运算。蓄水池抽样(Reservoir Sampling)问题分析

今日面试题:忘我之乘积

给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1]*A[2]*...*A[n]/A[i]。你不能使用除法运算。

蓄水池抽样(Reservoir Sampling)问题分析

问题:

要求从N个元素中随机的抽取k个元素,其中N无法确定。

这种应用的场景一般是数据流的情况下,由于数据只能被读取一次,而且数据量很大,并不能全部保存,因此数据量N是无法在抽样开始时确定的;但又要保持随机性,于是有了这个问题。所以搜索网站有时候会问这样的问题。

这里的核心问题就是“随机”,怎么才能是随机的抽取元素呢?我们设想,买彩票的时候,由于所有彩票的中奖概率都是一样的,所以我们才是“随机的”买彩票。那么要使抽取数据也随机,必须使每一个数据被抽样出来的概率都一样。

分析:

由于N无法确定,数据只能读取一次,并且要求随机,就是每个元素抽出的概率一样,都是k/N

面试的时候,经常会在纸上通过一个小的例子来找到好的解决方案。比如先让你从100个元素中等概率抽取出10个元素。后来又向集合中添加了20个元素,变成了120个元素等概率抽取10个,怎么样才能随着N的动态改变而让N无论等于多少时这N个元素都等概率被抽取呢?

解法一:最小k个指纹

找到一个哈希函数能产生随机数,同时用一个k个元素的堆用来保存最小的k个元素。那么过一遍所有的元素,计算每个的哈希值,通过堆来选择k个元素。

这个算法看起来很精妙,会有什么问题吗?(思考)

解法二:数学计算

先选中前k个, 从第k+1个元素到最后一个元素为止, 以1/i  (i=k+1, k+2,...,N) 的概率选中第i个元素, 并且随机替换掉一个原先选中的元素, 这样遍历一次得到k个元素, 可以保证完全随机选取。

看来简单的算法,怎么能确保每个元素被选中的概率是k/N?

任意元素G在i轮留下来的概率:

  1. P(G留下) = P(G已经存在) * P(G没有被替换)   
  2.          = P(G已经存在) * (1 - P(G被替换))   
  3.          = P(G已经存在) * (1 - P(第i个元素要替换某个元素) * P(某个元素是G))   
  4.          = (k/i) * (1 - (k/(i+1)) * (1/k))   
  5.          = (k/i) * (1 - (1/(i+1)))   
  6.          = (k/i) * (i/(i+1))   
  7.          = (k/(i+1))   

证毕!

这个题有很多的变种,比如,

给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。

从一个不知长度的文件中随机抽出k行。

从实时的搜索词中随机抽出k个词。

原文链接:http://www.ituring.com.cn/article/49301

责任编辑:陈四芳 来源: 图灵社区
相关推荐

2013-10-16 15:50:20

Google面试题

2013-10-16 15:57:39

数组二叉树

2011-01-05 10:32:58

企业数据中心运维管理北塔

2023-12-25 14:44:52

Java数组

2022-12-28 16:47:06

ICT

2011-09-09 10:10:13

SQL数据库点滴

2017-10-16 10:42:27

前端JavaScript浮点数

2021-04-20 14:15:42

人工智能机器学习

2010-06-13 11:05:52

2009-07-02 14:59:28

Java考研试题

2020-10-09 12:41:04

算法优化场景

2011-05-24 13:33:45

2011-04-15 13:12:09

.NETMEF

2011-02-13 13:04:00

HTML 5Web

2021-10-18 08:28:03

Kafka架构主从架构

2021-01-14 05:21:59

Hive抽样函数

2022-11-15 16:37:38

PyTorch抽样函数子集

2021-08-30 09:30:29

Kafka高性能设计

2023-09-11 13:27:00

数据训练

2009-11-30 10:21:41

点赞
收藏

51CTO技术栈公众号