#470 Implement Rand10() Using Rand7()

Description

Given the API rand7() that generates a uniform random integer in the range [1, 7], write a function rand10() that generates a uniform random integer in the range [1, 10]. You can only call the API rand7(), and you shouldn’t call any other API. Please do not use a language’s built-in random API.

Each test case will have one internal argument n, the number of times that your implemented function rand10() will be called while testing. Note that this is not an argument passed to rand10().

Examples

Example 1:

Input: n = 1
Output: [2]

Example 2:

Input: n = 2
Output: [2,8]

Example 3:

Input: n = 3
Output: [3,8,10]

Constraints:

1 <= n <= 1 0 5 10^5 105

Follow up:

What is the expected value for the number of calls to rand7() function?
Could you minimize the number of calls to rand7()?

思路

他其实是一个用 M M M随机数生成 N N N随机数的故事
M M M N N N有两种关系

  • M > N M > N M>N :因为在 [ 0 , N ] [0, N] [0,N] 的区间内,生成 [ 0 , N ] [0, N] [0,N] 的概率是相同的,所以如果生成数在 [ 0 , N ] [0, N] [0,N] 的区间内,可以直接使用,超过 N N N,就重新 rand 直到生成数在 [ 0 , N ] [0, N] [0,N] 的区间内
  • M < N M < N M<N:查看多少次 M M M的组合可以超过 N N N,即找到一个组合数 k,使得 M k > N M^k > N Mk>N,然后通过上一种方式生成随机数

如何利用 M k M^k Mk ?
n e w R a n d = M k − 1 × r a n d M ( ) + M k − 2 × r a n d M ( ) + ⋯ + M 0 × r a n d M ( ) new Rand = M^{k - 1} \times randM()+M^{k-2}\times randM()+\dots +M^0\times randM() newRand=Mk1×randM()+Mk2×randM()++M0×randM()

当然为了节省时间,又因为 M M M是以指数级别在上涨,在向下找区间时不用拘泥于 N N N本身,找到 N N N的倍数然后通过取余即可。

代码

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        int rand1 = rand7() - 1;
        int rand2 = rand7() - 1;
        
        int rand = 7 * rand1 + rand2;
        while (rand >= 40) {
            rand1 = rand7() - 1;
            rand2 = rand7() - 1;
            
            rand = 7 * rand1 + rand2;
        }
        
        return rand % 10 + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值