蓄水池算法

参考文章:http://www.cnblogs.com/ywl925/p/3793003.html

问题定义:

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

求解:

    蓄水池算法:

    蓄水池算法是针对从一个序列中随机抽取不重复的K个数,保证每个数被抽取到的概率都为K/N这个问题构建的

    做法:

            首先构造一个可以容纳k个元素的蓄水池,将序列前k个元素直接放入蓄水池中

            然后从第k+1个数据开始,以k/i(k<i=n)的概率来决定它是否进入蓄水池。

            当遍历完N个数据,蓄水池中所剩的K个元素就是就是挑选出的元素

            时间复杂度为O(N)

 

证明每个数被抽取到的概率都为K/N

    

对于第i个数(i<k),在前k步被选中的概率都是1,从第K+1步开始,每一步i不被选中的概率为依次为k/k+1,k+1/k+2...,那么读到第n个数时,就可以算出第i个数(i<k)被选中的概率=被选中的概率*以后每一步都不被换走的概率

即 1*(k/k+1)*(k+1/k+2)*...*(n-1/n) = k/n

对于第j个数(j>=k)被选中的概率为:在他出现时被选中的概率*在他出现后不被换走的概率,

即(k/j)*(j/j+1)*(j+1/j+2)*...*(n-1/n) = k/n

综上得证

 

关于蓄水池算法的几个文章:

蓄水池算法介绍和证明【原创】:http://www.cnblogs.com/aboutblank/p/4800874.html

算法【34】蓄水池抽样算法:https://www.cnblogs.com/python27/p/Reservoir_Sampling_Algorithm.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值