470 用Rand7实现Rand10

本文最后更新于:2022年4月9日 中午

已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。

不要使用系统的 Math.random() 方法。

示例 1:

1
2
输入: 1
输出: [7]

示例 2:

1
2
输入: 2
输出: [8,4]

示例 3:

1
2
输入: 3
输出: [8,1,10]

提示:

  1. rand7 已定义。
  2. 传入参数: n 表示 rand10 的调用次数。

进阶:

  1. rand7()调用次数的 期望值 是多少 ?
  2. 你能否尽量少调用 rand7() ?

Solution

参考:@Jerry

  • 从 rand10() 到 rand7()
  • 从 rand7() 到 rand10()

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public:
int rand10() {
// 首先得到一个数,在[1,49]之间
int num = (rand7() - 1) * 7 + rand7();
// 只要大于10,就不断生成,当范围在1-10之间,直接返回
while (num > 10) {
num = (rand7() - 1) * 7 + rand7();
}
return num;
}
};

改进:

这样的一个问题是,我们的函数会得到 1~49 之间的数,而我们只想得到 1~10 之间的数,这一部分占的比例太少了,简而言之,这样效率太低,太慢,可能要 while 循环很多次,那么解决思路就是舍弃一部分数,舍弃 41~49

因为是独立事件,我们生成的 1~40 之间的数它是等概率的,我们最后完全可以利用 1~40 之间的数来得到 1~10 之间的数。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int rand10() {
// 首先得到一个数,在[1,49]之间
int num = (rand7() - 1) * 7 + rand7();
// 只要大于10,就不断生成,当范围在1-10之间,直接返回
while (num > 40) {
num = (rand7() - 1) * 7 + rand7();
}
// 返回结果 +1,确保在[1-10]之间
return 1 + num % 10;
}
};

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!