470. 用 Rand7() 实现 Rand10() 拒绝采样

已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random() 方法。
示例 1:
输入: 1
输出: [7]
示例 2:
输入: 2
输出: [8,4]
提示:
rand7 已定义。
传入参数: n 表示 rand10 的调用次数。

解题思路

这个问题有两个形式:

  • rand 大数生成小数
  • rand 小数生成大数
    第一种
    譬如 rand10得到rand7:思路很简单,如果得到8-10,就继续调用重新采样,直到处于1-7为止。但是遇到 rand50得到rand7 呢?做个取余就好1-49 映射到 1-7很容易,50就继续循环调用
    第二种
    调用一次rand7只能得到7种结果,那如果调用两次呢?可以得到7*7=49种组合结果,生成 [1, 49] 之间的随机整数,我们只用到其中的 40 个,用来实现 Rand10(),而拒绝剩下的 9 个数
    在这里插入图片描述
# 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):
        """
        :rtype: int
        """
        idx = (rand7() - 1) * 7 + rand7()
        while idx>40: 
            idx = (rand7() - 1) * 7 + rand7()
        return (idx - 1) % 10 + 1
        # return idx % 10 + 1
优化

上一种方法中要舍弃[41,49],舍弃的有点多,可以想办法少丢弃一点。当产生的数在[41,49]时,利用 idx = (idx - 40 - 1) * 7 + rand7()=[1, 63],这样我们可以得到1-63之间的随机数,只要舍弃3个即可,那对于这三个舍弃的,还可以再来一轮,idx = (idx - 60 - 1) * 7 + rand7()=[1, 21],这样我们可以得到1-21之间的随机数,只要舍弃一个即可。

# 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):
        """
        :rtype: int
        """
        while True:
            idx = (rand7() - 1) * 7 + rand7()
            if idx<=40:
                return idx%10 + 1 
            idx = (idx - 40 - 1) * 7 + rand7()
            if idx<=60:
                return idx%10 + 1 
            idx = (idx - 60 - 1) * 7 + rand7()
            if idx<=20:
                return idx%10 + 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值