vlambda博客
学习文章列表

大厂程序员面试逻辑题面面观

大厂在校招时,相比项目经验,更看重候选人的潜力,除了数据结构与算法的掌握程度,逻辑题的解答状况也是候选人潜力的良好体现。不是程序员的朋友也可可以进来看看哦,不涉及专业知识。


首先要声明的是,逻辑题不是脑筋急转弯!逻辑题不是脑筋急转弯!逻辑题不是脑筋急转弯!重要的事情说三遍。有些难题不要怀疑不可能做到,只是还没有想到如何做到的方法,这就好比高智商犯罪,在揭晓真相之前,没有人知道凶手是如何杀人的。


Problem 1


我第一次面试遇到逻辑题是在腾讯暑期实习的一面,面试官问了这样一个问题:深夜里有4个人想要过桥,然而过桥需要打开手电筒,并且桥上只能同时站两个人,否则就会发生危险,他们只有一个手电筒,并且手电筒的电只能支撑17分钟,已知甲过桥需要10分钟,乙过桥需要5分钟,丙过桥需要2分钟,丁过桥需要1分钟,问这4个人能否平安过桥?


我最开始想的是让1分钟的老哥来回送手电筒,因为他的移动速度最快。然后我在脑海中进行了一番演绎:丙与丁一起过桥,花费2分钟;丁回来送手电筒,花费1分钟;丁与乙一起过桥,花费5分钟;丁回来送手电筒,花费1分钟;丁与甲一起过桥,花费10分钟。总共花费2+1+5+1+10=19分钟,超过了17分钟,证明这个思路是不正确的,还有用时更少的方法。


然后我发现了一个point得到了面试官的肯定,那就是让10分钟的老哥和1分钟的老哥一起过桥,不是对1分钟老哥的一种浪费吗?想到这里,问题迎刃而解。



到了揭晓真相的时候了:丙与丁一起过桥,花费2分钟;丁回来送手电筒,花费1分钟;甲和乙一起过桥,花费10分钟;丙回来送手电筒,花费2分钟;最后丙和丁一起过桥,花费2分钟。总共花费2+1+10+2+2=17分钟,因此这4个人可以平安过桥。


面完这一面,我突然意识到逻辑题在程序员面试中也会出现,就又去各大论坛搜罗了一些逻辑题研究,还有一位热衷于逻辑解谜的朋友也给我提供了很多不错的题目,我筛选了一些有代表性的题目放在了下面。


Problem 2

最少用几根绳子能够量出1小时15分钟?已知绳子是不均匀的,但是能够保证一根绳子点燃一端至烧尽的时间是1小时。


有的朋友会想着把绳子对折后剪断,对折两次剪断两次就得到了绳子的1/4,就能量出15分钟。这种思路是错的,因为绳子是不均匀的,任何人都不能保证对一根绳子对折后剪断得到的半截绳子就能燃烧半小时。


但是我们可以保证,如果从两边同时点燃绳子,烧尽的时间是半小时。


因此答案是这样的:最少需要使用3根绳子,标号A、B、C。同时点燃A的两端和B的一端,30分钟后A烧尽,B已经燃烧了30分钟,再点燃B的另一端,从点燃B的另一端到烧尽需要花费15分钟,这样完完全全烧完B就总共需要花费45分钟了。B烧尽的同时,点燃C的两端,C烧尽再花费30分钟。这样总共花费45+30=75分钟=1小时15分钟。


Problem 3


桶量水问题。这是论坛朋友反应在面试中遇到最多的一类题目。问题大都长这样:给你一个5L的桶、一个6L的桶和无限多的水,问你如何量出3L水。


我给大家准备一个屡试不爽的算法,先盛满容量大的桶,将容量大的桶的水再倒入容量小的桶,这样容量大的桶就有定量的剩余,再把容量大的桶剩余的水倒入容量小的桶,再灌满容量大的桶,再将容量大的桶的水再倒入容量小的桶,这样容量大的桶的剩余就会比上次多。依次类推,直到得到目标容量。


比如这道题,装满6L桶后倒满5L桶,6L桶剩1L,把5L桶倒干净后再把6L桶里剩余的1L水倒入5L桶;再装满6L桶后倒满5L桶,因为5L桶里已经有1L水了所以6L桶这次剩了2L水,把5L桶倒干净后再把6L桶里剩余的2L水倒入5L桶;再装满6L桶后倒满5L桶,因为5L桶里已经有2L水了所以6L桶这次剩了3L水,达得到了目标容量3L。


Problem 4


小白鼠试毒。已知有1000瓶酒,其中只有1瓶酒有毒。小白鼠喝一点酒,就会在24小时后死亡。比如今天8点喝的酒,明天8点就会死。今天8点让你开始用小白鼠试毒,明天8点就要得知哪瓶酒有毒,问你最少需要多少只小白鼠?


用1000只小白鼠可以吗?答案是肯定的,1000只小白鼠每人负责喝1瓶酒,今天8点让它们同时喝,明天8点哪只小白鼠死了哪瓶酒就有毒。


用999只小白鼠可以吗?答案也是肯定的,我相信这是大部分朋友的第一反应。999只小白鼠每人负责喝1瓶酒,今天8点让它们同时喝,明天8点如果没有小白鼠死亡,那就一定是剩下的没有分配小白鼠的那瓶酒有毒;如果有小白鼠死亡,那死亡的小白鼠喝的那瓶就就是有毒的酒。


可究竟最少需要多少小白鼠呢?要比999少的多,只需要10只。



既然想不明白1000瓶酒,那我们把问题简化,修改一下问题,8瓶酒中有1瓶酒有毒,最少需要多少只小白鼠?答案是3只。可能有的朋友已经想到了,对的,就是二进制编码。


8瓶酒分别给编号0-7,并将其转换成二进制,然后准备3个杯子,1号小白鼠喝第一杯,2号小白鼠喝第二杯,3号小白鼠喝第三杯:


编号
倒酒情况
000 不向任何杯子倒酒
001 向第三个杯子倒一滴酒
010
向第二个杯子倒一滴酒
011 向第二个和第三个杯子各倒一滴酒
100
向第一个杯子倒一滴酒
101
向第一个和第三个杯子各倒一滴酒
110 向第一个和第二个杯子各倒一滴酒
111 向三个杯子都各倒一滴酒


第二天8点......


如果没有小白鼠死亡,就是0号酒有毒;

如果3号小白鼠死亡,就是1号酒有毒;

如果2号小白鼠死亡,就是2号酒有毒;

如果2号和3号小白鼠死亡,就是3号酒有毒;

如果1号小白鼠死亡,就是4号酒有毒;

如果1号和3号小白鼠死亡,就是5号酒有毒;

如果1号和2号小白鼠死亡,就是6号酒有毒;

如果三只小白鼠都死亡,就是7号酒有毒。


因此,最少需要几只小白鼠就是看几位二进制数能够表示酒瓶数的个数,10位二进制数可以表示1000个数(2^9=512,2^10=1024,512<1000<=1024),因此鉴别1000瓶酒最少就需要10只小白鼠。


总结一个公式,设一共有n瓶酒,若2^x-1<n<=2^x,则x就是最少需要小白鼠的个数。


SUMMARY


逻辑题虽然容易让人摸不着头脑,但是也不难训练,可以多思考几个然后总结一下规律。衷心祝愿各位读者老爷能在这个金三银四的春天拿到梦想的offer。