leetcode中等470rand7实现rand10

Posted qq_40707462

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode中等470rand7实现rand10相关的知识,希望对你有一定的参考价值。

思路:

(1)由大的随机数 生成小的随机数是方便的,如 rand10 -> rand7
只需要用 rand10 生成等概率的 1 ~ 10 ,然后判断生成的随机数 num ,如果 num <= 7 ,则返回即可
在这里插入图片描述
在这里插入图片描述
(2)如何由小的随机数生成大的随机数呢?
考虑这样一个事实:
randX() 生成的随机数范围是 [1...X](randX - 1) * Y + randY() 可以等概率的生成的随机数范围是 [1, X*Y]

因此, 可以通过 (rand7 - 1) * 7 + rand7() 等概率的生成 [1...49]的随机数,我们可以选择在 [1…10] 范围内的随机数返回。

# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7

class Solution(object):
    def rand10(self):
        num = (rand7() - 1) * 7 + rand7()
        #只要它还大于10,那就给我不断生成,因为我只要范围在1-10的,最后直接返回就可以了
        while (num > 10):
            num = (rand7() - 1) * 7 + rand7();        
        return num;

在这里插入图片描述
(3)上面生成 [1…49] 而 我们需要 [1…10],[11…49]都要被过滤掉,效率有些低,可以通过减小过滤掉数的范围来提高效率。比如我们保留 [1…40], 去除 [41…49],[1 … 40] 可以1 + num % 10 等概率的映射到 [1…10]

class Solution(object):
    def rand10(self):
        num = (rand7() - 1) * 7 + rand7()
        while (num > 40):
            num = (rand7() - 1) * 7 + rand7();        
        return 1 + num % 10;

在这里插入图片描述

(4)那么如果生成的数在 [41…49] 怎么办呢?,这些数因为也是等概率的。我们可以重新把[41 … 49] 通过 num - 40 映射到 [1 … 9],可以把 [1…9] 重新看成一个通过 rand9 生成 rand10 的过程。

(大于40的随机数 - 40 - 1) * 7 + rand7() -> [1 ... 63]只要舍弃三个数

if(num <= 60) return num % 10 + 1

再来一轮:
(大于60的随机数−60−1)∗7+rand7()-> [1 ... 21]只要舍弃一个数

if( num <= 20) return num % 10 + 1

class Solution(object):
    def rand10(self):
        while True:
            num = (rand7() - 1) * 7 + rand7();
            #如果在40以内,那就直接返回
            if(num <= 40):
                return 1 + num % 10;
            #说明刚才生成的在41-49之间,利用随机数再操作一遍
            num = (num - 40 - 1) * 7 + rand7();
            if(num <= 60):
                return 1 + num % 10;
            #说明刚才生成的在61-63之间,利用随机数再操作一遍
            num = (num - 60 - 1) * 7 + rand7();
            if(num <= 20):
                return 1 + num % 10;

在这里插入图片描述

注意:这个映射的范围需要根据 待生成随机数的大小而定的。
比如我要用 rand7 生成 rand9
(rand7() - 1) * 7 + rand7() -> [1...49]
则等概率映射范围调整为 [1…45], 1 + num % 9
if(num <= 45) return num % 9 + 1

以上是关于leetcode中等470rand7实现rand10的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 470. 用 Rand7() 实现 Rand10()

Leetcode No.470 用 Rand7() 实现 Rand10()

Leetcode No.470 用 Rand7() 实现 Rand10()

LeetCode 470 用Rand7()实现Rand10()[数学] HERODING的LeetCode之路

精选力扣500题 第34题 LeetCode 470. 用 Rand7() 实现 Rand10()c++ / java 详细题解

LeetCode 470. Implement Rand10() Using Rand7()