【经典算法题】用两个鸡蛋和100层的楼来测鸡蛋硬度

前几天看到一个挺有意思的面试问题,据朋友说今年字节和Shopee都问过。
题目如下:

有2个鸡蛋,在总共有100层的楼上往下扔,以此来测试鸡蛋的硬度。比如鸡蛋在第9层没有摔碎,在第10层摔碎了,那么鸡蛋不会摔碎的临界点就是9层。
问:如何用最少的尝试次数,测试出鸡蛋不会摔碎的临界点?

朋友给了一个文档,里面收集了一部分今年大厂的智力题和解答,对于这题有详细的分析和解答,但是并不全面,尤其是在确定第一次扔鸡蛋的楼层数上。
--------------------下面是我的解答,可供参考--------------------
(一)二分法

这题要求最少的尝试次数,就是想出一种方案,可以让测试次数最少,而且这个次数是该方案下最坏的情况所需的次数。

首先把一枚鸡蛋从一半的楼高即50层往下扔。
如果第一枚鸡蛋在50层高就碎了,那第二枚鸡蛋就只能从第1层开始扔,不然碎了就没鸡蛋了,然后一直往上加楼层,最坏的情况是扔到第49层,共计50次。

如果第一枚鸡蛋在50层没碎,则继续使用二分法,在剩余楼层的一半(75层)往下扔,然后再区分碎与不碎的情况。。。。。。

后面无论什么情况,这种方法在最坏情况就是50次,显然最少次数不会这么大。

(二)区间平分法

考虑到第一种方法次数那么多,而且主要是因为第一次扔的楼层很高,那能不能降低第一次扔的楼层高度呢,但是太低的话(比如一楼开始扔),后面又得花费很多次了。让我们先看看把100层均匀分成10分的情况吧。

第一次在10层的位置扔,如果碎了,就从一楼开始扔,这样就只需要十次;但是第一次扔如果没碎,那最坏的情况就是到第100层的时候鸡蛋碎了,此时已经扔了10次(10,20,30…100),那就只能拿第二个鸡蛋从91层开始,一直到99,这样共计是19次。

我当时还想到,要是在第90层没碎的话,那就把90到100间二分一下,第二次从95层扔,要是碎了,那第二个鸡蛋就从91,92,93,94,总共14次,要是没碎,就继续二分,但关键就是,万一在第90层的时候就碎了呢,或者在第80层的时候就碎了呢,这个题目要给出最少次数,必须得考虑所有最坏的情况。

第一个鸡蛋碎与不碎、第一次扔的楼高、第二次,第三次以及后面每一次扔鸡蛋的楼高都能明显影响结果,既然情况这么复杂,那干脆就直接假设本题中最少尝试次数为x次,即鸡蛋硬度测试的最优方案下的最大次数是x次。

(三)假设法

在这里插入图片描述

这是一种逆行解法,我们假设已经知道最少尝试次数为x次。那么我们需要进一步确认第一次在哪一层扔鸡蛋。

1.显然,第一次扔的层数不能大于x,即不能从x+1及更上面的楼扔,因为如果第一个鸡蛋碎了,后面又得从一楼开始扔,这时尝试次数就是x+1及更大的数(比如第一次在第x+1层扔,碎了,那第二个鸡蛋最坏情况下得从1楼扔到x层,此时共计尝试1+x次),这与我们的假设相违背。

2.既然x次是最优方案最坏的情况,那我们干脆第一次在第x层扔。若第一个鸡蛋碎了,那最坏情况就是就从1楼一直扔到x-1楼,共计1+(x-1)=x 次。那如果没碎,怎么保证后面总计次数不超过x次呢?

按照上面的逻辑,第二次扔鸡蛋的楼高不能超过 x+(x-1),因为前面已经用过一次机会了,后面不能超过x-1次。此时最坏的情况就是,第一次在x层扔鸡蛋没碎,第二次在x+x-1层扔时碎了,那就得从第x+1层往上扔,这样总共次数为1+x-1=x次,没有超过,而且刚好为x次,按照这个逻辑,后面继续保持最少尝试次数为x次去找楼层(因为我们要考虑最坏的情况,在这个情况下,次数为x次)

那第三次就是只剩下x-2次机会,那我们在第
**x+(x-1)+(x-2)**层扔。一直扔到100。那么就有:

x+(x-1)+(x-2)+(x-3)+…+1 = 100 (1)

//最后一项为1是因为最后肯定会只剩1次尝试机会,若鸡蛋只在100层碎,那么左边加起来就是100,即最后一次扔鸡蛋是在第100层

按照前面每次选楼层的逻辑,此时总共尝试的次数就是x次,所以左边是x项。
则有数列求和

*(x+1)x / 2 = 100 (2)

解出x为小数,向上取整为x = 14。

//因为x得往大取整,(1)式左边才会大于100。又或者试想一下,左边项数必须小于x次,列出不等式(1)≤ *(x+1)x / 2,解出x > 13.72

那么这个时候,每次扔鸡蛋的楼层可以取值为

14,27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100
共12个数

可以尝试验证,比如鸡蛋在68层会碎,则在69时碎了,此时尝试6次,再拿第二个鸡蛋从61开始到68碎了,此时8次,共计14次,这时得到鸡蛋不会碎的临界层数是67层。

3.如果第一次扔的层数不是x次呢,显然也是可以的,比如x-1层,大家可以按照2的思路尝试算一下,发现x解出来也是14。我们可以假设第一次在第14-m层扔鸡蛋,后面也是按照2的思路,第二次只有13次机会,所以从**(14-m)+13**层扔,依次类推,可以解出105-m ≥ 100,所以m ≤ 5,即第一次从14、13、12、11、10、9层扔都是可以的。
如果第一次从第9层开始扔,那么每次的层数取值可以为

9、22、34、45、55、64、72、79、85、90、94、97、99、100
总共14个数

可以验证最大次数也是14。

4.扩展

如果第二次不按照x+x-1层来扔呢,而是按照小于这个层数来扔会怎么样,其实一样的,后面也是能变化的,但是最后加起来也是100,并且保证扔鸡蛋的次数最多还是14次,这样后面的层数也不能选太小,可见扔鸡蛋的方案还是很多的并不止
14,27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100 这一种

感觉这个假设法并不一定逻辑最严密,可能还有更严谨的解法。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值