广州4399面试题(二)
来源:互联网 发布:linux mv r 编辑:程序博客网 时间:2024/06/02 16:21
题目描述
现给定n个物品,其概率分别为P1, P2, P3...Pn,请设计一个接口,根据概率,随机获取一个物品。
算法分析
本题的算法可以使用《编程珠玑》中的算法实现,将概率抽象成线段,而后使用rand()%区间总长度,根据随机数所在的区间,确定选定哪个物品;现假设n=5,P1=10,P2=40,P3=5,P4=20,P5=25,那么将其转换成线段后如下图所示:
随机获取物品的情况如下图所示:
以上是假设概率均为整数的情况,对于概率有小数的情况,则根据其要保留的小数位数k,将其概率乘以10^k,并相应的将线段的总长度进行相应倍数的扩展。
一些问题
先验条件
- P1+P2+...+Pn=100%
- 0<=Pi<=1(1<=i<=n)
- n>0
可扩展性
对于需求变化小的情况,可以直接if-else if-...-else进行枚举,但是如果需求变动大,或者需要经常修改物品数量,就不能使用此种方法了。解决方案是动态计算,见时间复杂度VS空间复杂度小节。
时间复杂度VS空间复杂度
在采用动态计算时,可以指定一个数组,其内部存储类型为struct Range { int start; int end };在使用rand()%区间总长度获取随机数后,枚举此数组中的区间,即可获得相应的物品。此种方案可以有效的节约内存,但是每次调用rand()后,都需要做一次线性的查找,效率较低;
在现实世界中,此题目一般对应的案例为抽奖程序,那么就需要多次频繁地调用此函数,而且其运行在server端,内存并不是瓶颈,因此可以采用以空间换时间的办法来进行业务逻辑相关的优化。其算法如下:
依然假设n=5,P1=10,P2=40,P3=5,P4=20,P5=25。那么,就分配一个长度为100的数组,将物品区间填充成1,[10,50)区间填充成2,...,[75,100)区间填充成5(此过程只需进行一次,以后调用此函数无需重复填充),这样使用rand()%区间总长度获取随机数后,可以直接使用array[随机数]进行物品的获取,例如array[20]==2,其时间复杂度为O(1)。
经过以上的对比分析,可以得出在现实世界中,采用空间换时间的方案是最优解。
总结
解决此类题的时候,要注意题目中隐含的先验条件,还要注意接口的易用性(例如参数应该以什么形式传入/传出),还要取舍函数的可重入性,以及代码与业务逻辑之间的联系。
- 广州4399面试题(二)
- 广州4399面试题(二)
- 广州4399面试题(一)
- 广州4399面试题(一)
- android 面试题(广州)
- 广州宇信易诚科技有限公司面试题
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 面试题(二)
- 广州酷狗php面试题(赋答案)
- 广州捷宝电子面试题
- 广州某游戏公司的面试题
- 面向对象编程
- 广州4399面试题(一)
- Docker认识理解之路
- 移动端webApp滚屏特效、HTML5+CSS3手机整屏滚动 、mobile网站翻页滚屏特效!
- PHP编程效率的20个要点
- 广州4399面试题(二)
- 复杂和遗留的数据库schema
- 一个ul列表,让其前四个li显示,后面的隐藏。
- 检查OSD哪些配置有别于默认配置
- 我的自白书(二)
- Python字典对象实现原理
- 牛客网 | 寻找下一个结点
- Memcache应用场景
- C# Http地址下载文件到指定目录。