曾经,我非常羡慕那些人见人爱的人,我也想要变成那样,可是后来我才明白人见人爱也是需要天赋的,后来我开始默默努力,我想,就算我不能让每个人都喜欢我,至少因为我做的努力能得到别人的尊重。

扔鸡蛋问题

  腾讯面试的时候,面试官问了一道算法题,然后懵逼。。 遂记录于此。嗯,下面的题,有的是说鸡蛋,有的是说花瓶,但是实质都是一样的。 

  

1、 一个100层的楼,扔下一个鸡蛋(花瓶),怎么判断在N层不碎,N + 1层碎,思路是什么?

  因为就一个鸡蛋,所以,我们很容易就可以想到从第一层开始扔就可以了,直到碎,说明这是N + 1层。 

 

2、一个100层的楼,给你两个一模一样的鸡蛋(花瓶),判断这个鸡蛋的硬度,即N层不碎,N + 1层碎,最少需要多少次? 

方法一:遍历

  这里当然也可以按照第一个问题的方法来实现,即从第一层开始向上,直到摔碎为止,但是这种方法显然是低效的。

 

方法二二分查找

  当时就想到了使用这种方法,即采用二分查找的思路,第一次在50层扔:如果碎了,那么从第一层开始向上扔(因为就剩下这一个了,不能取中间值了)....; 如果没有碎,就在75层扔.....。 这样貌似速度快了不少,但是如果这个瓶子恰好是49层碎呢,那么就是在50层扔碎了一次,然后从第一层开始又扔了49次,一共花费了50次,这样的结果还不过第一种方法:即开始就从第一层扔,这样最后才49层。

  所以,这种方法也是不可取的。 

 

方法三动态规划

   其实,对于这个问题,我们可以将之转化为: 如果给定2个鸡蛋,n次抛鸡蛋实验,在最坏的情况下,可以保证测出多少层

  在这个问题中,我们需要注意的时可以保证测出多少层。 为了保证能够在有限的n次测试中测出需要的层数,我们需要首先考虑最坏的情况,也就是第一次抛鸡蛋蛋就碎了的情况;如果第一次就碎了,那么我们为了测出楼层就只能从底层开始一层层往上抛了(因为如果不是这样,比如我从碎了的下一层开始抛,那么如果鸡蛋也碎了,就说不清了)。

  这样,我们就确定了每次试验鸡蛋的起抛位置,那就是n层,因为在n层抛,即使碎掉了也可以保证在剩下的n - 1次试验当中,让鸡蛋覆盖这所有的n层楼,如果高于n这个数字就不可能了。

  那么,如果我们的第一次鸡蛋没有碎呢? 那么这个问题就很自然的转化为了:在最多n - 1次抛鸡蛋的试验中,可以保证测出多少层。 可以看出,这是一个典型的动态规划的问题。

  

  • 抛1次; 只能测出一层,毫无疑问。
  • 抛2次: 从2楼起抛,如果碎了,在1楼抛;没碎,转化成一个2个鸡蛋抛一次的问题(上面这个问题),所以抛两次可以测出2 + 1 = 3层。
  • 抛3次: 从3楼起抛,如果碎了,从1楼开始向上抛; 没碎,转化为一个2个鸡蛋抛两次的问题(上面这问题),所以抛3次可以测出3 + 3 = 6层。
  • 抛4次: 从4楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛三次的问题(上面这问题),所以抛4次可以测出4 + 6 = 10层。
  • 抛5次: 从5楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛4次的问题(上面这问题),所以抛5次可以测出5 + 10 = 15层。 
  • 抛6次: 从6楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛5次的问题(上面这问题),所以抛6次可以测出6 + 15 = 21层。
  • 抛7次: 从7楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛6次的问题(上面这问题),所以抛7次可以测出7 + 21 = 28层。
  • 抛8次: 从8楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛7次的问题(上面这问题),所以抛8次可以测出8 + 28 = 36层。
  • 抛9次: 从9楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛8次的问题(上面这问题),所以抛9次可以测出9 + 36 = 45层。
  • 抛10次: 从10楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛9次的问题(上面这问题),所以抛10次可以测出10 + 45 = 55层。
  • 抛11次: 从11楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛10次的问题(上面这问题),所以抛11次可以测出11 + 55 = 66层。
  • 抛12次: 从12楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛11次的问题(上面这问题),所以抛12次可以测出12 + 66 = 78层。
  • 抛13次: 从13楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛12次的问题(上面这问题),所以抛13次可以测出13 + 78 = 91层。
  • 抛14次: 从14楼起抛,如果碎了,从1楼开始向上抛;没碎,转化为一个2个鸡蛋抛13次的问题(上面这问题),所以抛14次可以测出14 + 91 = 105层。
  • 。。。
  • 。。。

  从上面的推断中,就已经可以看出14次,就可以测出105层了,所以100层也需要14次就可以测出来。

 

 

注意:

  可能有些同学即使大概理解,但是还不是能说清楚是否是最好情况还是最坏情况,那么我们只需要拿出其中一个例子来举例说明就可以了。 比如 2个鸡蛋抛3次能否测出一个6层高楼的临街位置,我们可以这么思考: 3次机会,我们第一次从3楼开始抛,如果碎了,那么剩下2个鸡蛋,2次机会一定可以找到临界位置,或者没有临界位置(即1层楼就会摔碎的情况); 如果3楼没有摔碎,那么就是说4/5/6三楼还有2个鸡蛋,两次机会,而实际上4/5/6可以看做1/2/3,那么我们就拿2个鸡蛋2次机会开始,第一次从2楼抛,如果碎了,那么还有一个鸡蛋一次机会一定可以可以找到的;如果没有碎,那么还有2个鸡蛋一次机会,也就可以测试3层是否会碎。所以,通过分析,2个鸡蛋抛3次可以测出一个6层楼高的临界位置,那么同样,2个鸡蛋14次机会也可以测出105层楼高的临界位置,那么100层也一定是可以的了。

 

 

 

参考文章:记两道ebay面试题

 

posted @ 2017-07-20 00:24  Wayne-Zhu  阅读(350)  评论(0编辑  收藏  举报

一分耕耘,一分收获。