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

题目描述

给定方法 rand7 可生成 [1,7] 范围内的均匀随机整数,试写一个方法 rand10 生成 [1,10] 范围内的均匀随机整数。

你只能调用 rand7() 且不能调用其他方法。请不要使用系统的 Math.random() 方法。

每个测试用例将有一个内部参数 n,即你实现的函数 rand10() 在测试时将被调用的次数。请注意,这不是传递给 rand10() 的参数。

示例1

输入: 1
输出: [2]

示例2

输入: 2
输出: [2,8]

提示:
1 <= n <= 105

进阶:

rand7()调用次数的期望值是多少 ?
你能否尽量少调用 rand7() ?

原题链接:https://leetcode.cn/problems/implement-rand10-using-rand7


根据题目描述,我们现在有一个能够获取[1,7]范围内随机数的方法,且范围内每个数字获取到的概率都是1/7。然后用这个方法去构造一个能够获取[1,10]范围内随机数的方法,且[1,10]每个数字的概率均为1/10。
根据独立随机事件的概率公式:P(AB)=P(A)*P(B) 我们不难想出,我们只需要构造能够均匀获得2种结果和5种结果的方法组合起来,即可得到10种结果且每种结果获取概率都相同的方法。
在本题中,我们可以先获取2种结果,以此来决定这个数是大于5还是小于5,但是题目给的方法是获取7种结果,那么我们就需要在获取到大于2的数时重新获取数字,直到获取到的数字小于等于2时(拒绝采样法)。

int a = Rand7(), ans;
while(a > 2) a = Rand7();
ans = (a - 1) * 5;

但是这样做的话,Rand7()调用次数的期望会比较高,我们可以对第二行代码做一个小优化,可以用数字a的奇偶性来决定得到的结果。需要注意的是1~7的7个数中,奇数比偶数多一个,所以需要拒绝其中一种为奇数的采样,那么第二第三行就可以改成

while(a == 7) a = Rand7();
ans = a%2 == 1? 0:5;

另一组结果采取同样思路,获取[1,5]的数字,加上前一组的结果即为想要得到的返回值。

int b = Rand7();
while(b > 5) b = Rand7();
ans += b;

整理一下得到完整代码:

public class Solution : SolBase {
    public int Rand10() {
        int a = Rand7(), b = Rand7();
        
        while(a == 7) a = Rand7();
        while(b > 5) b = Rand7();

        return (a%2 == 1?0:5) + b;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值