随机选取一个长度为N的链表(N很大)里的K个元素 - 编程珠玑

 随机选取一个长度为N的链表(N很大)里的K个元素 - 编程珠玑

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

解法1:

 

先选中前k个, 从第k+1个元素到最后一个元素为止, k/i (i=k+1, k+2,...,N) 的概率选中第i个元素,并且随机替换掉一个原先选中的元素, 这样遍历一次得到k个元素, 可以保证完全随机选取。这个算法叫做蓄水池抽样,在某门课上听到的,证明起来也不是很复杂。

可以参考编程珠玑问题12.10:如何从n个排序的对象中选择一个,但实现不知道n的大小?

解答:总是选择第一个对象,并使用1/2的概率选择第二个对象,使用1/3的概率选择第三个对象,以此类推。在过程结束时,每个对像被选中的概率都是1/n

详细解释:
应该是这样的吧,以k/i  (i=k+1, k+2,...,N) 的概率选中第i个元素。可以证明
对于前k个元素中的某一个最终能够被选中的情况是不被第k+1后的任意一个元素替换,其概率为k/n
对于第k个元素后面的某一个元素(假设为i)最终被选择的情况是,第i次被选中,从第i+1次以后不被任意元素替换,其概率为k/n
http://forum.byr.edu.cn/wForum/disparticle.php?boardName=ACM_ICPC&ID=33142&start=8&listType=1

你可能感兴趣的:(编程,算法,任务)