470. 用 Rand7 实现 Rand10
题目描述
已有方法rand7
可生成 1 到 7 范围内的均匀随机整数,试写一个方法rand10
生成 1 到 10 范围内的均匀随机整数。
不要使用系统的Math.random()
方法。
示例:
示例 1: 输入: 1, 输出: [7]
示例 2: 输入: 2, 输出: [8,4]
提示:
rand7
已定义;- 传入参数:n 表示
rand10
的调用次数。
来源:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-rand10-using-rand7
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路点拨
以小见大 · 计算推导
假设已知方法rand2()
可生成 [1,2] 的均匀随机整数,现在想要生成 [1,4] 的均匀随机整数,该如何考虑呢?
第 1 次尝试: rand2() + rand2()
结果只能取到 [2,4] 而且结果不是等概率的,减去1试试?
第 2 次尝试: (rand2() - 1) + rand2()
结果只能取到 [1,3] 而且结果不是等概率的,再对(rand2() - 1)
乘2试试?
第 3 次尝试: (rand2() - 1) * 2 + rand2()
功夫不负有心人! 通过 3 次尝试,终于可以得到 [1,4] 的范围,且取到 1,2,3,4 的概率均为:1/4。
问题来啦! 这对于 rand7()
是否有效呢?是否可以利用 rand7()
实现 rand49()
的效果呢?
rand7() => rand7() - 1 => (rand7() - 1) * 7
(rand7() - 1) * 7 + rand7()
此时得到整数 1 到 49 的概率均为: 1/49;
以此类推
推论成立!
图见真章 · 矩阵取位
由题意已知Rand7()
可生成 1 到 7 范围内的均匀随机整数
则随机得到整数 1 到 7 的概率均为: 1/7;
但是!要实现rand10()
还差点,该怎么办呢?
是不是似曾相识呢?熟悉嘛?熟悉就对啦!
根据已知推论
我们既可利用现有的rand7()
来实现rand49()
啦
言归正传!我们尝试用 [1,10] 来填充这个 7 * 7 的矩阵
随机得到整数 1 到 10 的概率为:
哎呀,好像不是等概率的哦 /(ㄒoㄒ)/
如果我们只用其中的前 40 个,而拒绝剩下的 9 个数呢?
则此时随机得到整数 1 到 10 的概率为:
就这样终于等概率啦!
我们只需要用到其中的前 40 个即可实现Rand10()
言归正传 · 终述
要利用rand7()
实现rand10()
第 1 步: 我们根据推导结论,利用rand7()
方法来随机选取 7 * 7 矩阵中的某个元素
第 2 步: 判断选出的元素是否属于前 40 个,如果不是需要返回第 1 步重新选取元素
第 3 步: 若该属于前 40 个,但是直接输出的话超出 [1,10] 的范围,该怎么处理呢?
第 4 步: 输出!结束进程!
思路梳理
示例代码
Python
# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7
class Solution:
def rand10(self):
"""
:rtype: int
"""
while True:
index = (rand7() - 1) * 7 + rand7()
if(index <= 40): return (index - 1) % 10 + 1
C
// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7
int rand10() {
while(true) {
int index = (rand7() - 1) * 7 + rand7();
if(index <= 40) return index % 10 + 1;
}
}