Description
Given the API rand7() that generates a uniform random integer in the range [1, 7], write a function rand10() that generates a uniform random integer in the range [1, 10]. You can only call the API rand7(), and you shouldn’t call any other API. Please do not use a language’s built-in random API.
Each test case will have one internal argument n, the number of times that your implemented function rand10() will be called while testing. Note that this is not an argument passed to rand10().
Examples
Example 1:
Input: n = 1
Output: [2]
Example 2:
Input: n = 2
Output: [2,8]
Example 3:
Input: n = 3
Output: [3,8,10]
Constraints:
1 <= n <= 1 0 5 10^5 105
Follow up:
What is the expected value for the number of calls to rand7() function?
Could you minimize the number of calls to rand7()?
思路
他其实是一个用
M
M
M随机数生成
N
N
N随机数的故事
M
M
M和
N
N
N有两种关系
- M > N M > N M>N :因为在 [ 0 , N ] [0, N] [0,N] 的区间内,生成 [ 0 , N ] [0, N] [0,N] 的概率是相同的,所以如果生成数在 [ 0 , N ] [0, N] [0,N] 的区间内,可以直接使用,超过 N N N,就重新 rand 直到生成数在 [ 0 , N ] [0, N] [0,N] 的区间内
- M < N M < N M<N:查看多少次 M M M的组合可以超过 N N N,即找到一个组合数 k,使得 M k > N M^k > N Mk>N,然后通过上一种方式生成随机数
如何利用
M
k
M^k
Mk ?
n
e
w
R
a
n
d
=
M
k
−
1
×
r
a
n
d
M
(
)
+
M
k
−
2
×
r
a
n
d
M
(
)
+
⋯
+
M
0
×
r
a
n
d
M
(
)
new Rand = M^{k - 1} \times randM()+M^{k-2}\times randM()+\dots +M^0\times randM()
newRand=Mk−1×randM()+Mk−2×randM()+⋯+M0×randM()
当然为了节省时间,又因为 M M M是以指数级别在上涨,在向下找区间时不用拘泥于 N N N本身,找到 N N N的倍数然后通过取余即可。
代码
/**
* 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 rand1 = rand7() - 1;
int rand2 = rand7() - 1;
int rand = 7 * rand1 + rand2;
while (rand >= 40) {
rand1 = rand7() - 1;
rand2 = rand7() - 1;
rand = 7 * rand1 + rand2;
}
return rand % 10 + 1;
}
}