【微软算法面试高频题】rand7()问题

这篇博客介绍了如何利用rand7()生成1到7的随机数,来构造一个均匀分布的rand10(),解决算法面试中的常见问题。解析中强调了对概率的理解,通过概率论和数学推理,展示了一种乘以7的方法来确保生成的随机数在1-10范围内等概率分布。此外,还讨论了提高效率的进阶技巧,并归纳了从randm()到randn()的一般解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想加入大厂面试刷题群的可添加微信(备注CSDN)
在这里插入图片描述

1. 题目

已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10()随机1~10。

2. 解析

这道题主要是考察的对概率的理解。

要保证rand10()在整数1-10的均匀分布,可以构造一个1-10n 的均匀分布的随机整数区间(n为任何正整数)。假设x是这个1-10n区间上的一个随机整数,那么x%10+1就是均匀分布在1-10区间上的整数。由于(rand7()-1)*7+rand7()可以构造出均匀分布在1-49的随机数(原因见下面的说明),可以将41~49这样的随机数剔除掉,得到的数1-40仍然是均匀分布在1-40的,这是因为每个数都可以看成一个独立事件。

在进入题目之前,我想先给读者举个例子。设想一个简单的例子,假设已知rand2()可以均匀的生成[1,2]的随机数,现在想均匀的生成[1,4]的随机数,该如何做呢?

我想如果你也像我一样第一次接触这个问题,那么很可能会这么考虑——令两个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

可以看到,使用这种方法处理的结果,最致命的点在于——其生成的结果不是等概率的。在这个简单的例子中,产生2的概率是50%,而产生1和3的概率则分别是25%。原因当然也很好理解,由于某些值会有多种组合,因此仅靠简单的相加处理会导致结果不是等概率的。

仔细观察上面的例子,我们尝试对 (rand2()-1) 这部分乘以 2,改动后如下:

(rand2()-1) × 2 + rand2() = ? ==> [1,3]
   0            +   1     = 1
   0            +   2     = 2
   2            +   1     = 3
   2            +   2  
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值