腾讯二面,我被 “赛马” 问题难住了

很难一次答对的经典面试题,处处是坑

大家好,我是鱼皮。

今天分享一道我曾经被难住了的面试题,也是一道大厂面试时经常会被问到的面试题,赛马问题。

题目其实不难,但是第一次被问到时,稍有不慎,就会答错。所以,一起来学习下吧!

问题

64 匹马 赛跑,没有任何秒表之类的计时工具,跑道每次只允许 8 匹马 同时比,问 最少 需要比赛几场才能够选出跑的最快的 前 4 名

题目描述就这么多,大家可以先思考一下,然后在投票中给出答案吧~

(投票)

下面公布解题思路和答案。

解题思路

这道题目坑点很多,题目中任何一个数字的改动都会影响到最终结果,因此一定要明确题目上的关键数字。

网上也有很多题目的变种,比如 36 匹马 6 个跑道找前三名,但思路都是一致的,下面我们模拟一下比赛全程。

第一轮

首先,跑道最多允许 8 匹马同时比,那我们一定要最大程度地利用资源,每场比赛都要上满 8 匹马。

所以第一轮最简单,无脑 将 64 匹马分为 8 组,每组 8 匹马比一场 就好了,共计 8 场比赛。

组号 参赛选手
组 1 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 2 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 3 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 4 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 5 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 6 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 7 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴
组 8 🐴 🐴 🐴 🐴 🐴 🐴 🐴 🐴

本轮比赛之后,由于题目要求选出前 4 名,因此,每组比赛第 4 名之后的马可以直接淘汰,还剩 32 匹马。

组号 参赛选手(🐎 = 组内冠军)
组 1 🐎 🐴 🐴 🐴
组 2 🐎 🐴 🐴 🐴
组 3 🐎 🐴 🐴 🐴
组 4 🐎 🐴 🐴 🐴
组 5 🐎 🐴 🐴 🐴
组 6 🐎 🐴 🐴 🐴
组 7 🐎 🐴 🐴 🐴
组 8 🐎 🐴 🐴 🐴

第二轮

第二轮开始,我们必须精打细算了。

最简单的方式是将剩下的 32 匹马直接分为 4 组去比赛,但其实利用上一轮的信息,我们可以有更好的方法。

让上轮比赛中,每组第 1 名一起比赛 1 场,然后按照本轮比赛结果,选出前 4 组。

赛场:🐎 🐎 🐎 🐎 🐎 🐎 🐎 🐎

比赛结果:

组号 参赛选手(🐎 = 组内冠军)
组 1 🐎 🐴 🐴 🐴
组 2 🐎 🐴 🐴 🐴
组 3 🐎 🐴 🐴 🐴
组 4 🐎 🐴 🐴 🐴
组 5 🐎 🐴 🐴 🐴

这么操作的原因是:如果某个组的第一名都进不了前 4,那这个组剩下的马肯定也进不了前 4,直接整组淘汰即可。

截止到目前,还剩下 16 匹马,那这一轮淘汰到这里就结束了么?

其实并没有,以这轮比赛排名第四的马所在的组为例,这个组的冠军最高也才第四名,那么这个组其他的马也是可以被淘汰的。同理,可以淘汰更多的马,剩余 10 匹。

组号 参赛选手(🐎 = 组内冠军)
组 1 🐎 🐴 🐴 🐴
组 2 🐎 🐴 🐴 🐴
组 3 🐎 🐴 🐴 🐴
组 4 🐎 🐴 🐴 🐴

现在场上还有 10 匹马,看似胜利近在咫尺,但其实,接下来才是关键!

第三轮

接下来我们的目标是从 10 匹马中选出前 4 名,但一场比赛只能容纳 8 匹马,那好像至少还得比两场。

一步步来吧,先选 8 匹马比一场呗,问题是选哪 8 匹马呢?

不知道大家有没有发现,在无意中,冠军已经产生了,那就是组内组外都未尝败绩的那匹***中之强!

组号 参赛选手(🐎 = 组内冠军)
组 1 🏆 🐴 🐴 🐴
组 2 🐎 🐴 🐴
组 3 🐎 🐴
组 4 🐎

因此,它不用再比了,目标变成,从剩余 9 匹马中选出第 2 - 4 名。

让我们任意选 8 匹马先比一场吧,选出前 3 名。

组号 参赛选手(🐎 = 组内冠军)
组 1 🏆 [ 🐴 🐴 🐴 ] 出战
组 2 [ 🐎 🐴 🐴 ] 出战
组 3 [ 🐎 🐴 ] 出战
组 4 🦓(未参与比赛的马)

那么最后一轮,还需要让上轮没比的马与前 3 名比 1 场,万一人家是黑马呢?

赛场:🐎 🐴 🐴 🦓

至此,答案出来了,最少需要 8 + 1 + 1 + 1 = 11 场。

然而,这是一个错误答案!

其实,还有更优解!

在还剩 9 匹马的时候,如果不任选 8 匹马比赛,而是先移除组 2 的冠军,让剩下 8 匹马赛一场。

如果这场比赛中,组 3 的冠军拿了第一,那么由于之前已经证明了组 2 的冠军强于组 3 的冠军,则前 4 名已经确定,只需要比 10 场。如果它不是第一,那么还是要多比一场了。

因此正确答案是,最少需要 10 场,你做对了么?


最后,为什么这道题目会出现在程序员面试中呢?聪明的你一定发现了,上述的赛马问题本质上是一个 TopN(取前几名)问题,可以通过分治的方式解决,是一种经典的算法思维。如果是在分布式系统中,则体现了 并行计算 的优势,可以利用资源(比如有 8 个跑道)对各个组同时计算,从而提高运算效率。此外,利用已有的数据结果也是非常重要的。

祝大家周末愉快,学到的话别忘了帮鱼皮点个 支持下吧!❤️

#面试题目##腾讯#
全部评论
?9匹马的时候移除组四冠军,只要组三冠军没进前二就不用再多比了啊
2 回复 分享
发布于 2021-04-18 11:50
昨天就被问了,说是智力题。。 然后说了几种TopK的思路,但没有给出最优解🤣
1 回复 分享
发布于 2021-04-24 22:08
感谢参与【创作者计划2期·技术干货场】!欢迎更多牛油来写干货,瓜分总计20000元奖励!!技术干货场活动链接:https://www.nowcoder.com/link/czz2jsghtlq(参与奖马克杯将于每周五结算,敬请期待~)
1 回复 分享
发布于 2021-04-22 17:25
锦标赛树?
1 回复 分享
发布于 2021-04-19 21:33
点赞 回复 分享
发布于 2021-04-18 00:18

相关推荐

09-23 20:21
门头沟学院 Java
先说一下个人的情况吧,bg学院本,学历很lj,鼠鼠高考后对我的冲击比较大,大学开学心里面就憋着一股劲,大学刚开学就开始在网上各种收罗互联网的信息,对我来说,我的大一上学期并不像其他学生一样多姿多彩,加各种各样的社团、各种聚餐什么的,凭着一心不甘,虽然知道学习成绩没有什么用,但还是和大多数刚入学的新生一样认认真真听着大学老师讲课,然后第一学期期末考试绩点出乎意料的排在本专业第一,也许是学校层次太差的缘故吧。大一上学期的迷迷茫茫中了解到Java这个方向,然后期末前就入坑了,然后大一下学期,大二上学期都在学习Java技术栈,虽然也走过了不少弯路,但也算是把Java那一套学的差不多了。大二下学期改了简历然后就开始背八股了,期间投了一会,但只收到一个面试,因为准备不充分也是意料当中的挂了。然后大二结束,干暑假工。到现在大三开学陆陆续续投了1000+,才2面试机会,也不知道是上天眷顾还是运气好,我在大二上学期加的一个boss的微信老板的朋友圈发布了招聘信息,因为他那边是初创公司,加上也缺人,鼠鼠也算是oc了。因为鼠鼠在大一就养成了天天泡图书馆的习惯,所以大学除了放假前就一直呆在图书馆,也可以知道鼠鼠的大学生活并不美好,一直都在为了那个offer而努力。当收到offer的那一刻,鼠鼠也是激动的留下来不争气的泪花,虽然是一个外包小厂,但这也是鼠鼠为数不多的机会了(实在不想在当误时间在学校了)。所以我就打算就这个offer了。收到offer后,我心里面的一块压了2年的石头也算是短暂的放松了一下。想着在去之前在学校好好玩呢,但回过头发现自己在学校并没有什么可以玩的东西,大学2年都是在图书馆度过的。因为前几天感冒了,就在图书馆彻彻底底学不进去了,每天就是玩手机,和群友聊聊天。一天下午没有课,就吃了药在宿舍躺了一下午。这种感觉对我来说是新奇的,或许对舍友来说是在再平常不过的事情,在床上刷着dy,何不快哉?但是当我想在宿舍躺平的时候发现,这里的一切都那么陌生,舍友们打着游戏非常快乐,自己没有打游戏的习惯,到了宿舍就只能躺在床上刷手机。看着别人快乐的大学生活我说我不羡慕那是假的,每天上上课,写写作业,就可以快乐的玩耍了。看着自己天天早上6.30的闹钟,心里面难免也会有一点落差。我自己清楚就算这样我秋招也不一定能够上岸,或许可能和天天打游戏的舍友一样的秋招结局。一想到这里鼠鼠心里面就开始动摇了,早知道这样那还不如珍惜来之不易的大学生活好好玩一下,但一想到为了家里面挣钱的家长就又打消了这个念头。虽然不知道为了这一切是否值得,但还是不亏于内心吧!刚刚吃了感冒药,头昏昏的在图书馆写下了自己心里面的絮絮叨叨以此来排解一下心情吧。
黄褐色的香葱饼干:学院本的话,相比就业我更推荐考研究生,当然肯定是往211以上去努力,我就是学院本大二下开始全力考研,付出了两年的努力考上了zzu,就业差距太大了,可能本科的时候连中厂的简历都过不了,但现在面临秋招,很多大厂都给了机会,当然这只是我的建议,每个人的情况都不一样。
你找实习最大的坎坷是什么
点赞 评论 收藏
分享
评论
15
51
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务