[路飞]_leetcode-470-用 Rand7() 实现 Rand10()

227 阅读2分钟

题目描述:

[题目地址]

已有方法 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() ?

解题思路

根据给定的 rand7() 可以获取到 1~7 的均匀随机整数,而本题要获取的是 1~10 的均匀随机整数,想要得到更大的数字,只能相乘或者相加。
所以首先想到的是利用 rand7()*rand7() 获取到 1~49 的均匀随机整数,但是直接相乘后获取到 1~49 并不是均匀的。
那如何才能通过 rand7() 获取到大于 7 的整数呢?
其实可以利用先乘后加的方式,实现如下: 首先让 rand7()-1 就得到了 0~6 的均匀整数,
0,1,2,3,4,5,6
然后让它们 *7 就得到了下面的一组数字,
0,7,14,21,28,35,42
再利用 rand7() 获取 1~7 的随机均匀整数填补空隙也就是加上 rand7(), 就得到了 1~49 的随机均匀整数,
舍弃掉 40> 的部分,其余部分 %10 +1 就得到了 1~10 的均匀整数。

演示

r1.png

r2.png

r3.png

r4.png

r5.png

r6.png

r7.png

代码实现

var rand10 = function() {
    while(true){
        let num = (rand7() - 1) * 7 + rand7();
        if(num <= 40) return num % 10 + 1;
        num = ( num - 40 - 1) * 7 + rand7();
        if(num <= 60) return num % 10 + 1;
        num = ( num - 60 - 1) * 7 + rand7();
        if(num <= 20) return num % 10 + 1;
    }
    return num;
};

至此我们就完成了leetcode-470-用 Rand7() 实现 Rand10()