经典面试题。
使用拒绝采样法可以让大的rand实现小的rand。
比如:
rand10() -> rand7()
只取1-7,其余重新随机即可。
现在就是让rand7扩域。
可以考虑如下式子:
rand49() = 7*(rand7() - 1) + rand7();
然后利用好每个数进行优化:
40以内取模,40以上变成rand9()再处理一次。
变成:rand63(),60以下取模,以上变成 rand3()再处理一次。
最后变成rand21().20以下取模,20以上直接舍去即可。
// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7
/*
class Solution extends SolBase {
public int rand10() {
// 首先得到一个数
int num = (rand7() - 1) * 7 + rand7();
// 只要它还大于10,那就给我不断生成,因为我只要范围在1-10的,最后直接返回就可以了
while (num > 10){
num = (rand7() - 1) * 7 + rand7();
}
return num;
}
}
*/
class Solution {
public:
int rand10() {
while(1){
int num = 7*(rand7() - 1) + rand7();
if(num<=40)return (num-1)%10+1;
num = 7*(num-40 -1)+rand7();
if(num<=60)return (num-1)%10+1;
num = 7*(num-40 -1)+rand7();
if(num<=20)return (num-1)%10+1;
}
return 1;
}
};