《LeetCode之每日一题》:139.用 Rand7() 实现 Rand10()
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:139.用 Rand7() 实现 Rand10()相关的知识,希望对你有一定的参考价值。
题目链接: 用 Rand7() 实现 Rand10()
有关题目
已有方法 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() ?
题解
法一:拒绝采样
参考官方题解
思路:
在拒绝采样中,如果生成的随机数满足要求,
那么就返回该随机数,否则会不断生成,
直到生成一个满足要求的随机数为止。
Tips
Tip1
(randX() - 1)*Y + randY() 可以等概率的生成
[1, X * Y]范围的随机数
证明:
randX()的范围[1, X],randX()-1的范围为[0, X-1]。
(randX() - 1) * Y的范围是[0, (X-1)*Y](非连续整数集),
(randX() - 1) * Y + randY()的范围自然就是[1, X * Y](连续整数集)
Tip2
①idx为什么不是 col*row
官方题解刚开始给出示例,乘的话,生成的数就不是等概率了,故不使用
②而是 idx = col + (row - 1) * 7
而加的话就可以使其等概率的生成数字,由于col = rand7()等概率生成1~7数字,每个数字出现的概率皆为1 / 7,
,row = rand7()同理,又idx = col + (row - 1) * 7中row减去一个常数,再整体乘一个常数,仍不改变其整体等概率性质
// 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 row, col, idx;
do{
row = rand7();
col = rand7();
idx = col + (row - 1) * 7;
}while(idx > 40);
return 1 + (idx - 1) % 10;
//return 1 + idx % 10;
}
};
法二:优化拒绝采样
思路:
我们重复利用法一中的拒绝的数据,即[41, 49],通过取余我们可以得到[1, 9]之间的随机数,
此时调用一次rand7()我们可以得到,[1, 63]之间的等概率出现的数字,同理我们拒绝[61, 63]之间的数字,取余,可以得到[1, 3]之间的数字
此时再调用一次rand7(),我们可以得到[1, 21]之间等概率出现的数字,取余,得到[1],
此时调用rand7()得到 [1, 7]之间数字,不满足题意,故我们不采用调用本次rand7(),我们回到调用两次rand7()生成[1, 49]之间的数字
// 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 row, col, idx;
while(true){
row = rand7();
col = rand7();
//range[1, 49]
idx = row + (col - 1) * 7;
if (idx <= 40){
return 1 + (idx - 1) % 10;
}
row = idx - 40;
col = rand7();
//range[1, 63]
idx = col + (row - 1) * 7;
if (idx <= 60){
return 1 + (idx - 1) % 10;
}
row = idx - 60;
col = rand7();
//range[1, 21]
idx = col + (row - 1) * 7;
if (idx <= 20){
return 1 + (idx - 1) % 10;
}
}
}
};
以上是关于《LeetCode之每日一题》:139.用 Rand7() 实现 Rand10()的主要内容,如果未能解决你的问题,请参考以下文章