从1-N的范围内随机取出K个数,并且不能重复值,如何高效取出?

来源:互联网 发布:suho知乎 编辑:程序博客网 时间:2024/04/29 23:56

一开始是从咱csdn上的一个讨论的问题看到的,我当时也稀里糊涂的发了个帖子,不过现在觉得我当时想的太简单了。就在那天上班回去的路上,我在想,大家都在聚焦于如何解决随机值重复,包括有人说借助hash法(这确实是解决重复的好方法),不过我要说的是,我们真的能取出这么多的随机数吗?换句话说,我们要平均调用多少次随机函数才能使不重复的随机数达到K个呢?

后来我推算了一下 得到结论:

平均要取:(N/(N-1))*(N/(N-1)) +(N/(N-2))*(N/(N-2))+...+(N/(N-K))*(N/(N-K))

这个数有多大呢,学过微积分的可以很容易的解决这个问题,平均值介于(N/x)*(n/x)在两端区间取积分的值,化简后,

平均值~O((NN/(N-k)),其中NN=N*N,所以,比如,N=10万,K=9.9万,则平均要调用1000万次才能取出9.9万个随机数。

了解了这个值后,可以考虑如果K>n的一半,那么可以考虑取另外(n-k)个数,然后剩下的是符合要求的,然后可以考虑借助hash来解决高效判断取出另外k个数(如果处理不好,即使取出了n-k个数,那些符合要求的k个数也很难踢出来).

 

另外,如果愿意牺牲内存来换取效率,则当k很接近N时,可以直接分配1..N的内存,然后取出N-K个随机数填到对应的内存中,标示填入的内存为不合要求,则,最后在进行一次内存扫描就可以找出符合要求的K个数,此时的效率是平均值+N(全局内存扫描要扫N个值),同样也可以利用该公式估计出是否采用次策略可以提高效率

原创粉丝点击