今天是我坚持写题解的第 32 天!

题目描述(Medium)
已有方法 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() ?
链接:https://leetcode-cn.com/problems/implement-rand10-using-rand7
方法一、暴力
这道题要求的等概率生成 1
到 10
之间的数,最容易想到的方法是调用 10
次 rand7()
再模上 10
加 1
即可。
但是,这种方法并不完全是等概率的。
因为,调用 10
次 rand7()
生成的数在 10
~ 70
之间(包含 70
,一共 61
个数),如果模上 10
的话,可以看到数字 0
出现的比其它数字多 1
。
然而,能过,请看 Java 一行代码:
class Solution extends SolBase {
public int rand10() {
// % 10得到的是0~9,+1才是1~10
return IntStream.range(0, 10).map(a->rand7()).sum() % 10 + 1;
}
}
运行结果如下:

方法二、进阶
进阶中要求我们尽量少的调用 rand7()
,那么,我们思考下还有没有其他方法。
我们可以考虑使用公式 (rand7() - 1) * 7 + rand7())
,这样算出来的值就位于 0~6 * 7 + 1~7 = 1 ~ 49
,如果模上 10
的话,可以看到数字 0
出现的次数比其它数字少 1
,直接提交以下代码发现无法通过全部用例。
class Solution extends SolBase {
public int rand10() {
return ((rand7() - 1) * 7 + rand7()) % 10 + 1;
}
}
通过观察,发现 (rand7() - 1) * 7 + rand7())
生成的数字在 1
~ 40
范围内模 10
出现 0
~ 9
的概率是相同的,所以,我们可以选择丢弃 41
~ 49
的部分。
代码如下:
class Solution extends SolBase {
public int rand10() {
while (true) {
int num = (rand7() - 1) * 7 + rand7();
// 生成的如果是41~49,则重新生成
if (num <= 40) {
return num % 10 + 1;
}
}
}
}
运行结果如下:

最后
如果对你有帮助,请点个赞吧,谢谢^^
也可以关注我的公号【彤哥来刷题啦】,每日分享题解,一起刷题,一起拿全家桶。




