leetcode 470. 用 Rand7() 实现 Rand10()
给定方法 rand7 可生成 [1,7] 范围内的均匀随机整数,试写一个方法 rand10 生成 [1,10] 范围内的均匀随机整数。
重点:古典概型;
参考:leetcode 470
答案:
1. 第一次rand7限定[1,6],判断奇偶性,概率是1/2
2. 第二次rand7限定[1,5],概率是1/5
3. 二者结合可以得出10种概率相同的结果
*/
class Solution extends SolBase {
public int rand10() {
int first, second;
while ((first = rand7()) > 6);
while ((second = rand7()) > 5);
return (first&1) == 1 ? second : 5+second;
}
}
拓展
这个题目的的第二小题答案:
int rand100() {
int first, second,third;
while ((first = rand7()) >4);
while ((second = rand7()) > 5);
while ((third = rand7()) > 5);
return (first-1)*25+(second-1)*5+third;
}
关于如何生成映射函数的探究:
文章基于这样一个事实 (randX() - 1)*Y + randY() 可以等概率的生成[1, X * Y]范围的随机数
应该是这样(randx() - 1) * Y的范围是【0, x-1, (x-1)*2, … , (x-1)Y】这么一个集合,加上randY()就相当于给这个集合中每一个元素及其后面加上并填充了【1…Y]之间的这些数,最后的范围才是【1,2,…,XY】。
我们来分析一下第二小题的代码,有人可能会问这里有三个部分,不符合“ (randX() - 1)*Y + randY() “的特性。但是不然,我们把(second-1)*5+third看成一个整体Y,X = (first-1),只要Y能等概率生成1 - 25范围内的数字,那么总体上看符合(randX() - 1)*Y + randY() 定律,再细看Y = (second-1)*5+third也是能等概率生成0-25范围内的数,因为third = rand5()。