蓄水池算法:全网寻找锦鲤,在不断登录的用户中抽10个用户,不能一次性从服务器中随机找
提示:蓄水池算法大多数是跟面试官聊天的算法,抽奖用的算法
题目
蓄水池算法:全网寻找锦鲤,请你在不断登录的用户中抽10个用户,不能一次性从服务器中随机找10个作为锦鲤,因为公司的服务器数据庞大,没法让你一次性随机抽取。
一、审题
这个就是所有互联网大厂公司们寻找锦鲤的方法:蓄水池算法
蓄水池算法
所谓蓄水池,就是先拿容量为10 的桶【做蓄水池】,放10个用户,然后在后续来的用户中,以10/N的概率决定是否要进桶,同时以1/10的概率扔掉桶中的一个用户,这样的话,等价于n个用户中一次性抽取10个锦鲤。
我们来论证蓄水池算法!
(1)就是先拿容量为10 的桶做蓄水池,放最初登录的10个用户;
(2)然后在后续来的用户中,以10/N的概率决定它是否要进桶;
(3)同时以1/10的概率随机扔掉桶中的一个用户
不妨设桶里面现在有10个用户,编号分别是1-10
现在新来11号用户,总共n=11,咱们以10/n的概率决定11号用户进桶与否?
那进桶的概率就是10/11
又以1/10的概率决定随机扔掉桶中的一个用户,比如仍3吧
那请问11留在桶中的概率是多少呢?显然是10/11与1/10的乘积,所以呢,就是1/11,这就是一次性11个用户中捞一个进桶的概率。
依次类推,你会发现,任意一个用户,留在在桶中的概率都是1/n
这种就是n个取1个的随机操作,找锦鲤也就是公平的
用蓄水池算法寻找锦鲤
公司们抽奖都是这么干的,你看微信抽奖,不就是这样吗?
(1)你报名参与抽奖,它就会把桶为k的蓄水池准备好,最开始来的这k个用户全部进桶
(2)然后后续来的用户总共构成n数量,以k/n的概率决定它是否进桶
(3)再以1/k的概率决定丢掉桶中的任意一个用户
这样的话,任意一个新用户进桶的概率就是k/n*1/k=1/n
总体来说,相当于从n中随机抽到了它作为锦鲤
最后留在蓄水池中的k个用户,就是锦鲤,他们进桶的概率不会出错,就是很随机,很公平的
总结
提示:重要经验:
1)蓄水池算法很巧吧,非常有趣,就是先拿容量为10 的桶做蓄水池,放最初登录的10个用户;然后在后续来的用户中,以10/N的概率决定它是否要进桶;同时以1/10的概率随机扔掉桶中的一个用户
2)面试的时候,你跟面试官说这个算法的核心思想,也就非常明白了,代码就不用写了。
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。