刷题使我快乐,满脸开心.jpg

  • 来源:力扣(LeetCode)
  • 链接:https://leetcode.cn/problems/implement-rand10-using-rand7/
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目

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

你只能调用 rand7() 且不能调用其他方法。请不要使用系统的 Math.random() 方法。

每个测试用例将有一个内部参数 n,即你实现的函数 rand10() 在测试时将被调用的次数。请注意,这不是传递给 rand10() 的参数。

示例 1:

输入: 1
输出: [2]

示例 2:

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

示例 3:

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

提示:

  • 1 <= n <= 105

进阶:

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

思路

首先需要明确,rand7的结果是不会全部用上并且均分到10份的,明确这一点之后,其实我们要保证的就是,我们生成的1-10的结果是概率相等的即可。
一次rand7不够10份,所以肯定不行,两次rand7理论上有49种情况,肯定是可以满足产出10份结果的,一种比较简单实现代码的方式呢,就是:

  • 第一个随机,找到奇偶性
  • 第二个随机,找到1-5,结合第一次随机的结果,得到1-10的最终结果

到这里其实没太多要说的了,看看两个进阶:

  • 进阶一,纯数学问题了,惭愧,基本忘差不多了
  • 进阶二,那我理解就是对49份结果最大化的利用就好,这里放一份官方答案,代码比较优雅~

至此,上代码

代码

不满足进阶二,但是易懂

func rand10() int {
    // 只取1-5
    num1 := rand7()
    for num1 > 5 {
        num1 = rand7()
    }
    // 只取1-6
    num2 := rand7()
    for num2 == 7 {
        num2 = rand7()
    }
    // 第二个数是偶数,那就返回6-10
    if num2 % 2 == 0 {
        return num1 + 5
    } else {
        // 第二个数是奇数,那就返回1-5
        return num1
    }
}

满足进阶二,需要一定理解,具体思路参见官方题解

func rand10() int {
    for {
        row := rand7()
        col := rand7()
        idx := (row-1)*7 + col
        if idx <= 40 {
            return 1 + (idx-1)%10
        }
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/implement-rand10-using-rand7/solutions/978527/yong-rand7-shi-xian-rand10-by-leetcode-s-qbmd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。