友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

470. 用 Rand7() 实现 Rand10()

给定方法 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() 可以生成 [1, 7] 的随机数,那么调用 10 次,则可以生成 [10, 70] 的随机数,然后除以 10 求余数则是 [0, 9],再加一即可。

看完题解,才发现自己是蒙对了。利用 \(("rand_X()" -1) * Y + "rand_Y()" → \[1, X*Y]\),就可以生成 \(\[1, X*Y]\),拒绝 \(\[10*N+1, X*Y]\) 的部分,即可获得想要的随机数。如果生成的数字在拒绝部分,则可以通过 \(X*Y - 10*N\) 可以获得 [1, Z] 的随机数,可以利用上述策略继续来生成想要的随机数。

  • 一刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-08-30 21:59:24
 */
public int rand10() {
  while (true) {
    int a = rand7();
    int b = rand7();
    int num = (a - 1) * 7 + b; // [1, 7*7]
    if (num <= 40) {
      return num % 10 + 1;
    }

    a = num - 40; // rand9
    b = rand7();
    num = (a - 1) * 7 + b; // [1, 9*7]
    if (num <= 60) {
      return num % 10 + 1;
    }

    a = num - 60; // rand3
    b = rand7();
    num = (a - 1) * 7 + b; // [1, 3*7]
    if (num <= 30) {
      return num % 10 + 1;
    }
  }
}