interview--- n长链表

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

解答:

题其实是编程珠玑习题12.10的推广,原题既是k=1的情况,关键就是想到可以替换以前已经选择的元素。
按照这个思路:
1. 对于前k个,全部选择,即选择集S里为前k个元素
2. 第k+i(i>0)个时,令r1=rand(1,k+i),如果r1>k,则保持现有的选择集合S不变
3. 如果r1<=k, 令r2=rand(1,k),并让第k+i元素(即当前元素)替换集合S里第r2个元素

归纳:
1. 如果N=k, 前k个全部选择,被选择概率p=1
2. 如果N=k+1, 第k+1个被选择的概率为p=k/(k+1),前k个被选择的概率为
p=1*(1/(k+1)+(k/(k+1))*((k-1)/k)) = k/(k+1)
3. 如果N=k+i,第k+i个被选择的概率为p=k/(k+i)=k/N,前k+i-1(N-1)个被选择的概率为
p=k/(k+i-1) * (i/(k+i) + (k/(k+i) * (k-1)/k) = k/(k+i-1) * (i/(k+i) +
(k-1)/(k+i)) =
k/(k+i-1) * (k+i-1)/(k+i) = k/(k+i) = k/N
[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值