昨天的每日一题

已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。

不要使用系统的 Math.random() 方法。

 

示例 1:

输入: 1
输出: [7]

示例 2:

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

示例 3:

输入: 3
输出: [8,1,10]

 

提示:

  1. rand7 已定义。
  2. 传入参数: n 表示 rand10 的调用次数。

 

进阶:

  1. rand7()调用次数的 期望值 是多少 ?
  2. 你能否尽量少调用 rand7() ?
Related Topics
  • 数学
  • 拒绝采样
  • 概率与统计
  • 随机化

  • 👍 317
  • 👎 0
  • 简单版

    public int rand10() {
            int randA = rand7();
            int randB = rand7();
            if (randA >= 5 && randB <=3){
                return rand10();
            }
            return (randA+randB)%10 + 1;
        }

    分析过程如下,和上次求质数LeetCode刷题【204】计数质数分析过程类似,先把结果都求出来,然后像是敲冰块游戏一样敲掉不需要的结果,剩下的就是我们需要的结果了。

    第一步,rand7只能取到1-7的值,要求到1-10的话,那么至少也要两个rand7来相加的情况处理,那么对求和情况分析

    图中数值为求和的结果

    那么可以看到,结果为8的概率最大,有7种可能,即7/49的概率。对图中结果再用10取余可以得到如下

    如图中锁标示出来的那样,如果把右上角,或者右下角的情况扣掉的话,那么结果所有数值的概率都是4/40的概率。所以显而易见的代码就如上那样出来了。

    另一个解法

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