
核心思路
这道题的核心思路就是:将已知的rand7(随机生成一个1-7的数)进行多次调用,使得它能够均匀生成一个1-10范围内的数。其中的关键就是要满足均匀生成,保证每个数字生成的概率相同,因此,我们可以考虑使用两个rand7,一个相当于十进制之中的十位,另一个相当于个位,两个7便能组成1-49范围的均匀随机整数。即
int ten = rand7(), one = rand7();
int randomNum = (ten - 1) * 7 + one;
这样生成的数如果是41-49无法满足均匀生成1-10范围的数,故会被拒绝,只有1-40才会被接受输出,我们对上边的randomNum取模即可输出结果。
int ans = (randomNum - 1) % 10 + 1;
完整代码
class Solution extends SolBase {
public int rand10() {
int ten, one, ans;
do{
ten = rand7();
one = rand7();
ans = (ten - 1) * 7 + one;//生成1~49的一个随机数
}while(ans > 40);//被拒绝,重复上述步骤再取一个随机数
return (ans - 1) % 10 + 1;//保证存在10; 0~9的随机数加一
}
}
不过,这样生成的过程中每次被拒绝的概率有9/49,故其调用rand7的次数期望会稍高,若想提高被拒绝时生成数字的利用率,可以对大于40的部分模10变成9个数作为十位在次重复上边的操作变成生成范围1-63的随机数,这样就只会浪费3个数,然后再次重复变成1-21的随机数,这样就只会浪费一个数,算是非常理想了。
网友评论