您的位置:首页 > 职场人生

测试鸡蛋的硬度:一道关于查找的面试题

2016-09-28 11:19 190 查看
一道关于查找的面试题。

当时有点思维定式,懵逼的状态,没有解答好。

题目是这样的:

  背景:在你面前有一栋楼,总高200层,你手里有两个鸡蛋,并且两个鸡蛋的硬度相同,并且鸡蛋的硬度通过从某层楼上落下是否摔碎来定义,假设鸡蛋从20楼落下没有碎,但是从21楼落下碎了,那么就认为鸡蛋的硬度是20。

 那么问题来了:利用你手里仅有的两个鸡蛋和你面前的这栋楼,准确测试除鸡蛋的硬度,要求考虑到测试过程的效率。

从算法的角度分析,这个情景其实是要写一个对有序序列的查找算法。

当时思维定式,一直想着二分查找法,那么如果第一次从100层丢下一个鸡蛋恰好碎了,那么就只能老老实实从1楼一层一层往上爬...,时间复杂度就不是log_n而会变成n/2,因为最多只有2次试探的机会。显然性能是很差的。

然后思考的各种思路都被这种定势的思维局限,在面试的那5分钟之内都没有想到好的方法。

然而昨晚躺床上睡不着,和室(基)友促膝长谈,一番讨论被点拨了一下,突然就灵光乍现了。所以说果然当你的思维陷入一个定势的怪圈,还是需要有人能拉你一把的。

因为只有两个鸡蛋,用二分的试探性查找很显然是不太可取的,极端情况下性能会非常差。

那么不用二分,用m分呢?

假设我先从10楼丢下一个鸡蛋,如果碎了,就用剩下的一个鸡蛋从一楼一层层往上找;如果10楼丢下没碎,那么再尝试20楼,碎了的话就从11楼开始一层层往上找。

这种方法是可行的,并且如果m值选取得当,最坏情况的时间复杂对会比二分情况下的时间复杂度低得多。

不妨列一个简单的式子,找出最恰当的m值。

考虑最坏的情况:

需要查找(丢鸡蛋)的次数为

               O(n)=n/m+m;

在上面的例子中,n的取值为200,我们需要通过这个式子求出当O(n)最小时,m的取值。

它的图像在第一象限(m必须是大于零的)是一个类似于“√”的形状,有一个最小值,那么可以对这个式子求导数,当倒数为零的时候,m的取值会使O(n)最小,即

               0=-n/m^2+1;

得到m取值应该为√n,所以也就得出当m取值为√n时,该情景的查找时间复杂度为2√n。

这是目前我想到的最优的算法,不知道是否还有更优的算法呢,期待有研究的大神不吝赐教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: