1、题目
已有方法 rand7
可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10
生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random()
方法。
示例 1:
输入: 1
输出: [7]
示例 2:
输入: 2
输出: [8,4]
示例 3:
输入: 3
输出: [8,1,10]
提示:
rand7
已定义。- 传入参数:
n
表示rand10
的调用次数。
进阶:
rand7()
调用次数的 期望值 是多少 ?- 你能否尽量少调用
rand7()
?
2、思路
定理
若rand_n()
能等概率生成1
到n
的随机整数,则有(rand_n() - 1) * n + rand_n()
能等概率生成1
到n * n
的随机整数。
举例
(rand7()-1) * 7 + rand7()
: 相加元素无重复, 即等概率构成了 1~49
, 即rand49()
注: 即在0,7,14,21,28,35,42
基础上等概率加1, 2, 3, 4, 5, 6, 7
。
即:
第一个rand7
为0
时,再加上第二个rand7()
可以生成:1, 2, 3, 4, 5, 6, 7
(均为
1
/
7
1/7
1/7概率)
第一个rand7
为1
时,再加上第二个rand7()
可以生成:8, 9, 10, 11, 12, 13, 14
以此类推
第一个rand7
为7
时,再加上第二个rand7()
可以生成:43, 44, 45, 46, 47, 48, 49
(均为
1
/
7
1/7
1/7概率)
我们只需要[1,10]
范围内的整数,但是会生成[1,49]
范围内的整数,相当于有
4
/
5
4/5
4/5的数字都是无用的,需要重新生成。因此,我们需要尽可能多的充分利用[1,49]
范围内的数字。
方法是选择 [1, 40]
范围里的数,通过取余运算来得到 [1, 10]
范围的数,这里我们为了简化代码将[1,40]
的数字都减1
,取成[0,39]
数字x | x%10余数 |
---|---|
0, 10, 20 , 30 | 0 |
1,11,21,31 | 1 |
2,12,22,32 | 2 |
… | |
9,19, 29,39 | 9 |
余数0
到9
出现的概率都是相等的,最后再加1
取到[1,10]
。
3、c++代码
// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7
class Solution {
public:
int rand10() {
int t = (rand7() - 1) * 7 + rand7(); // 取到1~49之间的数字
if (t > 40) return rand10(); //如果数字大于40,再次进行rand7()运算
return (t - 1) % 10 + 1; //0~9余数加一取到1~10
}
};
4、java代码
/**
* The rand7() API is already defined in the parent class SolBase.
* public int rand7();
* @return a random integer in the range 1 to 7
*/
class Solution extends SolBase {
public int rand10() {
int t = (rand7() - 1) * 7 + rand7(); // 取到1~49之间的数字
if (t > 40) return rand10(); //如果数字大于40,再次进行rand7()运算
return (t - 1) % 10 + 1; //0~9余数加一取到1~10
}
}
原题链接:470. 用 Rand7() 实现 Rand10()
最近一直在刷力扣题,计划是刷完500道力扣高频面试题,有想一起组队刷题的或者在刷题上有困惑的小伙伴可以加我微信或者QQ,免费答疑。备注算法学习即可。
微信:z13663570205
QQ:1622840727
![](https://i-blog.csdnimg.cn/blog_migrate/6545193fbfac485a4ec5683a0ea52913.png)
如果我的文章对你有帮助的话,还请点个赞鸭!!!