博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解题思路:蓄水池问题
阅读量:7058 次
发布时间:2019-06-28

本文共 698 字,大约阅读时间需要 2 分钟。

在面美团实习的时候,面试官问了这道蓄水池问题:给定一个链表,长度未知(但是大于k),你只能遍历一次,要求随机挑出k个节点。

刚听完题目的我是一脸蒙蔽的,what is the fuck? 长度未知?遍历一遍?那每个节点被挑选的概率如何计算?

我当时的答案是遍历两遍链表。

后来想想这样的确很蠢,蓄水池问题的一个变种:有一个网络数据流,要你随机抓一个包,所有包被抓到的概率要求相等。

如果用我的遍历两遍链表的方法肯定不行!

 

然后我google了一下,发现了神奇的蓄水池解法:

  对于链表随机挑k个节点,先把前k个节点作为已经选定的节点,从第k+1个节点开始,每个节点以1/(k+1)的概率被选中,并从选定的节点中随机挑选一个替换它,成为新的候选节点。

vector
vec(k,0);int num = k,curlen = k+1;while(num--){ vec[k-num] = head->val; head = head->next;}while(head){ int m = rand()%curlen; if(m < k) swap(vec[m],head->val); head = head->next; curlen++;}

  这样一来,第i个节点被选中的概率为1/i。而它之前的节点i-1被选中的概率为 1/(i-1)*(1-1/i) = 1/i。满足题意。这个思路实在是666。

转载于:https://www.cnblogs.com/unclelin/p/6565389.html

你可能感兴趣的文章
spring redis 配置子域名共享session (有点坑)
查看>>
Linux 条件变量 pthread_cond_signal及pthread_cond_wait
查看>>
比AtomicInteger更高效的并发计数器LongAdder
查看>>
Forms开发中触发器的执行顺序
查看>>
SEO博客三个月没更新排行骤步康复
查看>>
JQuery 插件开发的入门介绍
查看>>
马哥2016全新Linux+Python高端运维班第五周作业
查看>>
联想扬天A4680R台式电脑增加内存不识别的解决方案
查看>>
(5)Powershell别名(Alias)
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
linux配置NTP Server
查看>>
PBDOM操作XML文档轻松入门
查看>>
双机热备 纯软 镜像 实战 安装前准备
查看>>
2011 Web设计的10大趋势
查看>>
认真对待数据库中char和varchar
查看>>
DDL和DML的定义和区别
查看>>
Spring+Quartz实现定时任务的配置方法
查看>>
rsyslog日志格式介绍
查看>>
SAP 设置或取消仓库不参与MRP运算
查看>>