暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【每日一题】470. 用 Rand7() 实现 Rand10():一题两解:Java 一行代码 & 进阶!

彤哥来刷题啦 2021-09-05
159

今天是我坚持写题解的第 32 天!

题目描述(Medium)

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

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

示例 1:

输入: 1 

输出: [7]

示例 2:

输入: 2 

输出: [8,4]

示例 3:

输入: 3 

输出: [8,1,10]

提示:

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

进阶:

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

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

方法一、暴力

这道题要求的等概率生成 1
10
之间的数,最容易想到的方法是调用 10
rand7()
再模上 10
 加 1
即可。

但是,这种方法并不完全是等概率的。

因为,调用 10
rand7()
生成的数在 10
~ 70
之间(包含 70
,一共 61
个数),如果模上 10
的话,可以看到数字 0
出现的比其它数字多 1

然而,能过,请看 Java 一行代码:

class Solution extends SolBase {
    public int rand10() {
        // % 10得到的是0~9,+1才是1~10
        return IntStream.range(010).map(a->rand7()).sum() % 10 + 1;
    }
}

运行结果如下:

image-20210905004623061

方法二、进阶

进阶中要求我们尽量少的调用 rand7()
,那么,我们思考下还有没有其他方法。

我们可以考虑使用公式 (rand7() - 1) * 7 + rand7())
,这样算出来的值就位于 0~6 * 7 + 1~7 = 1 ~ 49
,如果模上 10
的话,可以看到数字 0
出现的次数比其它数字少 1
,直接提交以下代码发现无法通过全部用例。

class Solution extends SolBase {
    public int rand10() {
        return ((rand7() - 1) * 7 + rand7()) % 10 + 1;
    }
}

通过观察,发现 (rand7() - 1) * 7 + rand7())
生成的数字在 1
~ 40
范围内模 10
出现 0
~ 9
的概率是相同的,所以,我们可以选择丢弃 41
~ 49
的部分。

代码如下:

class Solution extends SolBase {
    public int rand10() {
        while (true) {
            int num = (rand7() - 1) * 7 + rand7();
            // 生成的如果是41~49,则重新生成
            if (num <= 40) {
                return num % 10 + 1;
            }
        }
    }
}

运行结果如下:

image-2021090501075781

最后

如果对你有帮助,请点个赞吧,谢谢^^

也可以关注我的公号【彤哥来刷题啦】,每日分享题解,一起刷题,一起拿全家桶。

文章转载自彤哥来刷题啦,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论