Reservoir Sampling - snapchat

首先说一下Reservoir Sampling的原理

ref: http://www.geeksforgeeks.org/reservoir-sampling/

如果输入的Stream里面有N个数,我们需要从中选取k个随机的数,那么:

先把前k个数放入“水塘”(index范围是[0, k - 1])

从index为[k,N - 1]中的第i个数中,随机生成一个[0, i - 1]的值r

如果r < k那么就把res[r]换成stream[i]

分析其中的概率:

对于第i个数,它被换入水塘的概率是 k/i,并且在下一次替换中,下一个数被替换进去的概率是 k/i+1,刚好替换到它的概率是 1/k,所以它下一轮中,被替换出来的概率是k/i+1 * 1/k = 1/i+1,所以,它在下一轮中没有被替换出来的概率是 1 - 1/i+1 = i/i+1。

所以,直到最后一个数为止,它留在水塘中的概率是 k/i * i/(i+1) * (i+1)/(i+2) * ... * (n-1)/n = k/n

对我来说……这个已经很难了…………= =

需要注意的是Random r = new Random(). int nextInt = r.nextInt(k). nextInt的值的范围是[0, k-1],不包括k

面经里的题的意思是,给你一个数组,在所有最大的元素里,随机选出一个坐标返回,要求每个坐标被选中的概率一样。

“具体请参考 给你一个输入 nums = [1, 4, 5, 2, 3, 5, 1, 3, 5], 然后impement一个getMaxIndex。 这里因为最大值是5,所以有2,5,8三个index。只用返回一个。要求是这三个index被返回的概率要相等。只能用O(1)的extra space. ”

本题做法:

对于一个数组,从头走到尾,如果它是当前最大的数,就结果是它,如果遇到好几个一样的最大的数,就在它的计数cnt中,随机生成[0, cnt]的值,如果rint < k(此处是1),即rint == 0的时候,更换maxIdx。

走完之后返回maxIdx的值

代码:

 1     public int getMaxIdx(int[] stream) {
 2         int cnt = 1;
 3         int max = stream[0];
 4         int maxIdx = 0;
 5         Random r = new Random();
 6         for (int i = 1; i < stream.length; i++) {
 7             if (stream[i] == max) {
 8                 cnt++;
 9                 if (r.nextInt(cnt) == 0) {
10                     maxIdx = i;
11                 }
12             } else if (stream[i] > max) {
13                 cnt = 1;
14                 maxIdx = i;
15                 max = stream[i];
16             }
17         }
18         return maxIdx;
19     }

时间复杂度是O(n), extra space是O(1)。

我是在太机智了哈哈哈哈哈哈

时间: 2024-08-06 16:04:38

Reservoir Sampling - snapchat的相关文章

Reservoir Sampling - 蓄水池抽样

问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the objects sequentially but you do not know the value of n beforehand? For concreteness, how would you read a text file, and select and print one random l

Reservoir Sampling

Reservoir sampling is proposed to solve such set of problems: Randomly choose items from a stream of elements where could be very large or unknown in advance, i.e., all elements in the stream are equally likely to be selected with probability The alg

Spark MLlib之水塘抽样算法(Reservoir Sampling)

1.理解 问题定义可以简化如下:在不知道文件总行数的情况下,如何从文件中随机的抽取一行? 首先想到的是我们做过类似的题目吗?当然,在知道文件行数的情况下,我们可以很容易的用C运行库的rand函数随机的获得一个行数,从而随机的取出一行,但是,当前的情况是不知道行数,这样如何求呢?我们需要一个概念来帮助我们做出猜想,来使得对每一行取出的概率相等,也即随机.这个概念即蓄水池抽样(Reservoir Sampling). 水塘抽样算法(Reservoir Sampling)思想: 在序列流中取一个数,如

reservoir sampling / random shuffle

randomly choose a sample of k items from a list S containing n elements, the algorithm may be online (i.e. the input list is unknown beforehand) https://en.wikipedia.org/wiki/Reservoir_sampling ReserviorSampling(Source[1..n], Result[1..k]) { for (int

Reservoir Sampling 蓄水池抽样算法,经典抽样

随机读取数据,如何保证真随机是不可能的,因为计算机的随机函数是伪随机的. 但是在不考虑计算机随机函数的情况下,如何保证数据的随机采样呢? 1.系统提供的shuffle函数 C++/Java都提供有shuffle函数,可以对容器内部的数据打乱,保持随机排序. C++: 1 template <class RandomAccessIterator, class URNG> 2 void shuffle (RandomAccessIterator first, RandomAccessIterato

68. 蓄水池抽样(Reservoir Sampling)

[本文链接] http://www.cnblogs.com/hellogiser/p/reservoir-sampling.html 问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the objects sequentially but you do not know the value of n beforehand? For concreteness

leetcode_398 Random Pick Index(Reservoir Sampling)

Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array. Note:The array size can be very large. Solution that uses too much extra spa

Reservoir Sampling - 蓄水池抽样算法

蓄水池抽样——<编程珠玑>读书笔记 382. Linked List Random Node 398. Random Pick Index         问题:如何随机从n个对象中选择一个对象,这n个对象是按序排列的,但是在此之前你是不知道n的值的.  思路:如果我们知道n的值,那么问题就可以简单的用一个大随机数rand()%n得到一个确切的随机位置,那么该位置的对象就是所求的对象,选中的概率是1/n. 但现在我们并不知道n的值,这个问题便抽象为蓄水池抽样问题,即从一个包含n个对象的列表S中

Random Pick Index

Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array. Note: The array size can be very large. Solution that uses too much extra sp