蓄水池抽样算法形式一

视频链接

B站视频链接

使用场景

给定一个数据流,数据流长度N很大,且N直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据(O(N))的情况下,能够随机选取出m个不重复的数据

伪代码

保证了每个字符串的取值概率都是等概率的;
image.png

  1. public String core(String[] lines) {
  2. int i = 0;
  3. String res = null;
  4. for(String line : lines) {
  5. i++;
  6. r = random.nextDouble();
  7. if(r < 1/((double)i)) {
  8. res = line;
  9. }
  10. }
  11. return res;
  12. }

形式二

题目链接

力扣 - 随机数索引
image.png

实现代码

  1. class Solution {
  2. int[] nums;
  3. Random random;
  4. public Solution(int[] nums) {
  5. this.nums = nums;
  6. random = new Random();
  7. }
  8. public int pick(int target) {
  9. int ans = 0;
  10. for (int i = 0, cnt = 0; i < nums.length; ++i) {
  11. if (nums[i] == target) {
  12. ++cnt; // 第 cnt 次遇到 target
  13. if (random.nextInt(cnt) == 0) {
  14. ans = i;
  15. }
  16. }
  17. }
  18. return ans;
  19. }
  20. }