【LeetCode】用 Rand7() 实现 Rand10()

简介: 【LeetCode】用 Rand7() 实现 Rand10()

【LeetCode】用 Rand7() 实现 Rand10()

rand7表示可生成 1 到 7 范围内的均匀随机数,rand10生成 1 到 10 范围内的均匀随机整数。

如果使用rand10去实现rand7,这个就很容易,我们只要舍弃掉大于 7 的数就可以了。

那么反过来怎么搞呢?

首先我们要能表示出来 1 到 10 这几个数,当rand7生成的最大数为 7 ,此时使用 7 表示8-14就如下所示:

7 + 1 = 8
7 + 2 = 9
7 + 3 = 10
7 + 4 = 11
7 + 5 = 12
7 + 6 = 13
7 + 7 = 14

对于上面的计算,我们可以表示在一个 7 的基础上,加上一个随机的1-7,表示8-14的随机数,抽象公式为:7 + rand7()

如果还需要知道15 - 21,那就是在两个 7 的基础上,加上一个1-7的随机数,接下来我们看看下面这个式子:

0 * 7 + rand7() => [1,7]
1 * 7 + rand7() => [8,14]
2 * 7 + rand7() => [15,21]
3 * 7 + rand7() => [22,28]

关于上面的式子,如果我们使用公式表示为:a * Y + rand_Y(),此时表示的是在 Y 的基础上,随机出现比它更大的一个范围的数,如果我们要把这些[1,7],[8,14],[15,21]小范围串起来,并保证[1,21]这些数的出现的几率一样,那么此时就要保证a出现的数字概率是一样的。此时公式就可以变为(rand_X() - 1) * Y + rand_Y()。这个式子表示可以等概率的生成[1, X * Y]范围的随机数。

(rand_X() - 1) * Y + rand_Y() => [1, X * Y]

看完公式的由来,接着看这道题,这里只有rand7(),直接把它套进公式,它能表示的范围是[1,49],我们可以使用生成的数除以 10 ,然后取余数,最后加上 1 ,表示随机生成 1-10

10 % 10 = 0 => 0 + 1 = 1
11 % 10 = 1 => 1 + 1 = 2
……
19 % 10 = 9 => 9 + 1 = 10

因为这个只能到 49,而不是到 50,所以导致最后的生成 2-10的概率要比 1高一些,所以这时候我们要用到“拒绝采样”了,这就是表示如果采样的数值不在要求范围之内,我们就要舍弃掉。然后我们就要把大于40的数舍弃掉。

public int rand10() {
    int num = (rand7() - 1) * 7 + rand7();
    while (num > 40) {
        num = (rand7() - 1) * 7 + rand7();
    }
    return num % 10 + 1;
}

当然也可以做一些优化,尽量减少要舍弃的数值,提高命中率。

public int rand10() {
    int num = (rand7() - 1) * 7 + rand7();
    while (num > 40) {
        // 生成的数在41-49之间,再操作一遍就在 1-63 之间了
        num = (num - 40 - 1) * 7 + rand7();
        if (num <= 60)
            return num % 10 + 1;
        // 生成的数在61-63之间,再操作一遍就在 1-21 之间了
        num = (num - 60 - 1) * 7 + rand7();
        if (num <= 20)
            return num % 10 + 1;
        // 重新生成随机数
        num = (rand7() - 1) * 7 + rand7();
    }
    return num % 10 + 1;
}
目录
相关文章
|
7月前
|
算法 Java C语言
C++和Java中的随机函数你玩明白了吗?内附LeetCode470.rand7()爆改rand10()巨详细题解,带你打败LeetCode%99选手
C++和Java中的随机函数你玩明白了吗?内附LeetCode470.rand7()爆改rand10()巨详细题解,带你打败LeetCode%99选手
|
机器学习/深度学习 算法 C++
每日算法系列【LeetCode 470】用 Rand7() 实现 Rand10()
每日算法系列【LeetCode 470】用 Rand7() 实现 Rand10()
102 0
LeetCode 470. 用 Rand7() 实现 Rand10()
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
88 0
|
程序员
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
117 0
【Leetcode】225. 用队列实现栈、232. 用栈实现队列
|
存储 前端开发 算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
171 0
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈
|
存储 算法 索引
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
leetcode【栈与队列—简单】 225. 用队列实现栈
leetcode【栈与队列—简单】 225. 用队列实现栈
leetcode【栈与队列—简单】 225. 用队列实现栈
leetcode【栈与队列—简单】 232. 栈实现队列
leetcode【栈与队列—简单】 232. 栈实现队列
leetcode【栈与队列—简单】 232. 栈实现队列
leetcode【字符串—简单】28.实现 strStr()
leetcode【字符串—简单】28.实现 strStr()
leetcode【字符串—简单】28.实现 strStr()