精选力扣500题 第34题 LeetCode 470. 用 Rand7() 实现 Rand10()c++ / java 详细题解

Posted 林深时不见鹿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精选力扣500题 第34题 LeetCode 470. 用 Rand7() 实现 Rand10()c++ / java 详细题解相关的知识,希望对你有一定的参考价值。

1、题目

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

2、思路

定理

rand_n()能等概率生成1n的随机整数,则有(rand_n() - 1) * n + rand_n()能等概率生成1n * n的随机整数。

举例

(rand7()-1) * 7 + rand7(): 相加元素无重复, 即等概率构成了 1~49, 即rand49()

注: 即在0,7,14,21,28,35,42 基础上等概率加1, 2, 3, 4, 5, 6, 7

即:

第一个rand70时,再加上第二个rand7()可以生成:1, 2, 3, 4, 5, 6, 7 (均为 1 / 7 1/7 1/7概率)

第一个rand71时,再加上第二个rand7()可以生成:8, 9, 10, 11, 12, 13, 14

以此类推

第一个rand77时,再加上第二个rand7()可以生成:43, 44, 45, 46, 47, 48, 49 (均为 1 / 7 1/7 1/7概率)

我们只需要[1,10] 范围内的整数,但是会生成[1,49] 范围内的整数,相当于有 4 / 5 4/5 4/5的数字都是无用的,需要重新生成。因此,我们需要尽可能多的充分利用[1,49] 范围内的数字。

方法是选择 [1, 40] 范围里的数,通过取余运算来得到 [1, 10] 范围的数,这里我们为了简化代码将[1,40]的数字都减1,取成[0,39]

数字xx%10余数
0, 10, 20 , 300
1,11,21,311
2,12,22,322
9,19, 29,399

余数09出现的概率都是相等的,最后再加1取到[1,10]

3、c++代码

// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7

class Solution {
public:
    int rand10() {
        int t = (rand7() - 1) * 7 + rand7();  // 取到1~49之间的数字
        if (t > 40) return rand10(); //如果数字大于40,再次进行rand7()运算
        return (t - 1) % 10 + 1; //0~9余数加一取到1~10
    }
};

4、java代码

/**
 * 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 t = (rand7() - 1) * 7 + rand7();  // 取到1~49之间的数字
        if (t > 40) return rand10(); //如果数字大于40,再次进行rand7()运算
        return (t - 1) % 10 + 1; //0~9余数加一取到1~10
    }
}

原题链接:470. 用 Rand7() 实现 Rand10()


最近一直在刷力扣题,计划是刷完500道力扣高频面试题,有想一起组队刷题的或者在刷题上有困惑的小伙伴可以加我微信或者QQ,免费答疑。备注算法学习即可。

微信:z13663570205

QQ:1622840727

如果我的文章对你有帮助的话,还请点个赞鸭!!!
在这里插入图片描述

以上是关于精选力扣500题 第34题 LeetCode 470. 用 Rand7() 实现 Rand10()c++ / java 详细题解的主要内容,如果未能解决你的问题,请参考以下文章

精选力扣500题 第4题 LeetCode 3. 无重复字符的最长子串 c++详细题解

精选力扣500题 第30题 LeetCode 5. 最长回文子串c++ / java 详细题解

精选力扣500题 第42题 LeetCode 155. 最小栈c++/java详细题解

精选力扣500题 第34题 LeetCode 470. 用 Rand7() 实现 Rand10()c++ / java 详细题解

精选力扣500题 第60题 LeetCode 76. 最小覆盖子串c++/java详细题解

精选力扣500题 第20题 LeetCode 704. 二分查找c++详细题解