问题描述

能否从一个未知大小的集合中随机抽取水塘抽样 - 图1个元素,使得水塘抽样 - 图2个元素的被选中的概率相等,要求只能遍历一次集合?

结论

设集合大小为水塘抽样 - 图3,只要在遍历过程中,令第水塘抽样 - 图4个元素被选中的概率为水塘抽样 - 图5,就可以使得最终每个元素被选中的概率为水塘抽样 - 图6

证明

使用归纳法证明

  1. 归纳基础:当水塘抽样 - 图7时,显然水塘抽样 - 图8即所有元素都被选中,每个元素被选中的概率为 1。
  2. 归纳假设:假设当水塘抽样 - 图9时,结论也成立。
  3. 归纳推理:则当水塘抽样 - 图10时,根据结论有第水塘抽样 - 图11个元素被选中的概率为水塘抽样 - 图12,此时对于前面水塘抽样 - 图13个元素中的某一个元素(第水塘抽样 - 图14个,水塘抽样 - 图15)仍然被选中的概率为:水塘抽样 - 图16,结论也成立。(水塘抽样 - 图17表示第水塘抽样 - 图18个元素被选中且恰好替换了第水塘抽样 - 图19个元素的概率)。
  4. 由(1)(2)(3)可知,结论成立。

应用场景

当集合很大且大小未知,不适合一次性加载到内存中时。

练习题目

题目来源:[LeetCode]382. 链表随机节点
解析:根据进阶要求,题目可以简化为从一个很大的集合中,等概率随机返回其中一个元素,对应水塘抽样 - 图20的水塘抽样。