「思路精讲」 用 Rand7() 实现 Rand10()

题目描述

已有方法rand7可生成 1 到 7 范围内的均匀随机整数,试写一个方法rand10生成 1 到 10 范围内的均匀随机整数。
不要使用系统的Math.random()方法。

示例:

示例 1: 输入: 1, 输出: [7]
示例 2: 输入: 2, 输出: [8,4]

提示:

  • rand7 已定义;
  • 传入参数:n 表示rand10的调用次数。

来源:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-rand10-using-rand7
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路点拨

以小见大 · 计算推导

假设已知方法rand2()可生成 [1,2] 的均匀随机整数,现在想要生成 [1,4] 的均匀随机整数,该如何考虑呢?

第 1 次尝试: rand2() + rand2()

结果只能取到 [2,4] 而且结果不是等概率的,减去1试试?

第 2 次尝试: (rand2() - 1) + rand2()

结果只能取到 [1,3] 而且结果不是等概率的,再对(rand2() - 1)乘2试试?

第 3 次尝试: (rand2() - 1) * 2 + rand2()

功夫不负有心人! 通过 3 次尝试,终于可以得到 [1,4] 的范围,且取到 1,2,3,4 的概率均为:1/4

问题来啦! 这对于 rand7() 是否有效呢?是否可以利用 rand7() 实现 rand49() 的效果呢?

rand7() => rand7() - 1 => (rand7() - 1) * 7

(rand7() - 1) * 7 + rand7()

此时得到整数 1 到 49 的概率均为: 1/49;

以此类推

推论成立!

图见真章 · 矩阵取位

由题意已知Rand7()可生成 1 到 7 范围内的均匀随机整数

则随机得到整数 1 到 7 的概率均为: 1/7;

但是!要实现rand10()还差点,该怎么办呢?


是不是似曾相识呢?熟悉嘛?熟悉就对啦!

根据已知推论

我们既可利用现有的rand7()来实现rand49()

言归正传!我们尝试用 [1,10] 来填充这个 7 * 7 的矩阵

随机得到整数 1 到 10 的概率为:

哎呀,好像不是等概率的哦 /(ㄒoㄒ)/

如果我们只用其中的前 40 个,而拒绝剩下的 9 个数呢?

则此时随机得到整数 1 到 10 的概率为:

就这样终于等概率啦!
我们只需要用到其中的前 40 个即可实现Rand10()

言归正传 · 终述

要利用rand7()实现rand10()
第 1 步: 我们根据推导结论,利用rand7()方法来随机选取 7 * 7 矩阵中的某个元素

第 2 步: 判断选出的元素是否属于前 40 个,如果不是需要返回第 1 步重新选取元素

第 3 步: 若该属于前 40 个,但是直接输出的话超出 [1,10] 的范围,该怎么处理呢?


第 4 步: 输出!结束进程!

思路梳理

示例代码

Python

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

class Solution:
    def rand10(self):
        """
        :rtype: int
        """
        while True:
            index = (rand7() - 1) * 7 + rand7()  
            if(index <= 40): return (index - 1) % 10 + 1 

C

// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7

int rand10() {
    while(true) {
        int index = (rand7() - 1) * 7 + rand7(); 
        if(index <= 40) return index % 10 + 1; 
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李不咕咕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值