leetcode【中等】470、rand7实现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;

在这里插入图片描述

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

(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值