当前位置:网站首页>leetcode-470.用 Rand7() 实现 Rand10()
leetcode-470.用 Rand7() 实现 Rand10()
2022-07-27 19:58:00 【KGundam】
数学问题
题目详情
给定方法 rand7 可生成 [1,7] 范围内的均匀随机整数,试写一个方法 rand10 生成 [1,10] 范围内的均匀随机整数。
你只能调用 rand7() 且不能调用其他方法。请不要使用系统的 Math.random() 方法。
每个测试用例将有一个内部参数 n,即你实现的函数 rand10() 在测试时将被调用的次数。请注意,这不是传递给 rand10() 的参数。
示例1:
输入: 1
输出: [2]
示例2:
输入: 2
输出: [2,8]
示例3:
输入: 3
输出: [3,8,10]
思路:
我们先考虑,使用rand2()可以生成[1,2]的随机数,那么如何得到[1,4]呢?
是不是一下想到用rand2()+rand2()呢?
rand2() + rand2() = ? ==> [2,4]
1 + 1 = 2
1 + 2 = 3
2 + 1 = 3
2 + 2 = 4
为了把生成随机数的范围缩小成[1,n],于是在上一步的结果后减1
(rand2()-1) + rand2() = ? ==> [1,3]
0 + 1 = 1
0 + 2 = 2
1 + 1 = 2
1 + 2 = 3
可以看到,这样生成的结果虽然是[1,3]但是概率却不相等,所以是不能用的
那如果我们把(rand()2-1)×2呢?(这里怎么想到的我TM也不知道)我们发现
(rand2()-1) × 2 + rand2() = ? ==> [1,4]
0 + 1 = 1
0 + 2 = 2
2 + 1 = 3
2 + 2 = 4
概率竟然完全相等,我们已经通过rand2()实现了rand4()
于是我们得出一个数学规律:
已知 rand_N() 可以等概率的生成[1, N]范围的随机数
那么:
(rand_X() - 1) × Y + rand_Y() ==> 可以等概率的生成[1, X * Y]范围的随机数
即实现了 rand_XY()
我们再想一个问题:如何反过来通过rand4()实现rand2()呢?我们可以通过取余实现
rand4() % 2 + 1 = ?
1 % 2 + 1 = 2
2 % 2 + 1 = 1
3 % 2 + 1 = 2
4 % 2 + 1 = 1
事实上,只要N是2的倍数,我们都可以通过randN()来实现rand2(),是等概率的!
反之如果N不是2的倍数通过取余是得不到等概率的,如:
rand6() % 2 + 1 = ?
1 % 2 + 1 = 2
2 % 2 + 1 = 1
3 % 2 + 1 = 2
4 % 2 + 1 = 1
5 % 2 + 1 = 2
6 % 2 + 1 = 1
rand5() % 2 + 1 = ?
1 % 2 + 1 = 2
2 % 2 + 1 = 1
3 % 2 + 1 = 2
4 % 2 + 1 = 1
5 % 2 + 1 = 2
有了上面的规律方法,我们可以分析本题了,需要我们通过rand7()实现rand10()
那么我们可以先实现randN()–N为10的倍数,然后取余
我们通过上面规律进行处理:
(rand7()-1) × 7 + rand7() ==> rand49()
但是49不是10的倍数啊!我们可以利用"拒绝采样"(不想要哪个采样结果就拒绝它)
把rand49()产生的41~49全部拒绝掉再取余就好了…
代码:
// 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()
{
while (true)
{
int num = (rand7() - 1) * 7 + rand7(); // 得到[1,49]
if (num <= 40) // 拒绝采样,得到[1,40]
return num % 10 + 1; // 取余得到[1,10]
}
}
};
优化
我们在上面的方法中,"拒绝采样"了41-49,那么我们能不能合理利用这九个数,从而提高生成随机数的效率,我们可以利用41-49减去40得到rand9()进一步得到rand10(),这时候我们发现再次处理后又"拒绝"61-63三个随机数,我们再利用其减去60得到rand3()进一步得到rand10(),这时最后只"拒绝"了21一个数,我们无需再处理,至此结束,提高了随机数的命中率
// 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()
{
while (true)
{
int a = rand7();
int b = rand7();
int num = (a - 1) * 7 + b; // rand49()
if (num <= 40) return num % 10 + 1; //拒绝采样得到rand10()
//下面的代码处理上面得到的无用的随机数[41,49]
a = num - 40; // rand49()-rand40()=rand9()
b = rand7();
num = (a - 1) * 7 + b; // rand63
if (num <= 60) return num % 10 + 1; //拒绝采样得到rand10()
//下面的代码处理上面得到的无用的随机数[61,63]
a = num - 60; // rand3
b = rand7();
num = (a - 1) * 7 + b; // rand21
if (num <= 20) return num % 10 + 1; //拒绝采样得到rand10()
//再往下就无法再物尽其用了,因为只剩了一个21了
}
}
};
边栏推荐
- Chapter 3 business function development (choose to export market activities, Apache POI)
- iptables学习
- Quartus:Instantiation of ‘sdram_model_plus‘ failed. The design unit was not found.
- 细胞CLE19多肽荧光成像牛血清白蛋白荧光猝灭量子点的制备
- MediaTek and Samsung launched the world's first 8K TV that supports Wi Fi 6
- ConvNeXt:A ConvNet for the 2020s——模型简述
- If there is no reference ground at all, guess if you can control the impedance?
- 【图解】三次握手,四次挥手 —— 用心看这一篇就够了
- How to quickly pass the probation period for newly trained intermediate test engineers
- mmu学习总结
猜你喜欢

饿了么input输入框设置type=‘number‘时,去掉后面的上下按钮

Buuctf brushes eleven questions (05)

How to quickly pass the probation period for newly trained intermediate test engineers

leetcode15--三数之和
DP traceability problem

七大排序之直接插入排序

多肽KC2S修饰白蛋白纳米粒/靶向肽GX1修饰人血清白蛋白纳米粒探针的研究制备

ConvNeXt:A ConvNet for the 2020s——模型简述

一篇搞定Redis中的BigKey问题

Hill sort of seven sorts
随机推荐
Kubernetes二进制部署——理论部分
【无标题】
Time relay
C语言详解系列——函数的认识(5)函数递归与迭代
Metersphere financial company landing experience sharing
Leetcode-226-flip binary tree
Leetcode383 ransom letter
第八章 通过 REST 使用 Web 会话(Sessions)
2022/5/31考试总结
解决ip地址访问末位奇数通偶数不通,或者偶数通奇数不通的问题(云加密机连接云服务器时遇到的问题,全程记录,希望能给大佬们灵感)
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
追源码的平凡之路
dBm和Vpp以及Vpeak的关系
紫光FPGA解决口罩难题!助力口罩生产全面提速
Kubernetes binary deployment - theoretical part
Shandong football match
10 years of technical career, those technical books that make me excited
What is private traffic?
Maximum sum of jz42 continuous subarray (force buckle) (GIF diagram)
OPPO Find X2系列发布:3K+120Hz曲面屏,DXO评分第一,顶配版6999元!