该题由于太过于经典,现在已经不是Google的面试题了

思路讲解
大家可能存在的疑问解答
例题:LeetCode 887 鸡蛋掉落
PS:(蓝桥杯摔手机就是根据扔鸡蛋过来的)

思路讲解

你有两个鸡蛋,在一百层的楼上,尽可能少的尝试次数可以找出在那一层掉落而不碎

吐个槽先

正如昨天所说,这道题据说它最早见于谷歌的某次面试,由于题目表述容易,而解答相对麻烦,于是被很多人采用,广泛见于一些算法、规划的面试里。

要说清楚这个问题有点难度,有兴趣的小伙伴务必要静下心来仔细看。

首先我想说,该问题的情境构造是有缺陷的。因为在现实中,影响鸡蛋是否会破裂的最重要因素应该是地面的坚硬和平整程度,而不是鸡蛋下落的高度:把鸡蛋从100层楼顶扔进棉花堆,和从2楼扔向坚硬的水泥地面:依常识判断,还是后者更容易碎。就像那句话说的,能够杀死你的是突然的速度改变,而不是高速本身:你会在接触地面的一瞬间死去,而不是死于高速坠落。

不过你懂的,这是题目,认真你就输了。

我们只需要遵循题目本身的设定就好,吐槽可以,不改变事实。

一个鸡蛋的无助

为了更好地解释这个问题,让我们先看一个简化的情况:如果你手头只有一个鸡蛋,该如何找到这个最高安全楼层?

——显然只能一层层地试。

简单地说,这个过程就是先在1楼把鸡蛋扔下地,看看碎不碎。

碎了,那么得到最高安全楼层为0。

如果没碎,那么拾起这个鸡蛋,上2楼,再扔下地,看碎不碎。

同样,碎了,那么得到最高安全楼层为1;没碎,那就再拾起鸡蛋奔3楼……

重复这个过程,直到发生两个结果之一:鸡蛋在第N层上首次碎掉,那么得到最高安全楼层为N-1;或者鸡蛋一直没碎,最高安全楼层为100(其实应该大于100,但这道题默认最大是100,所以姑且认为是100)。

由于鸡蛋随时可能会在某一层突然碎掉,而且一旦碎掉就再也没有鸡蛋可用,所以在整个过程中不能有任何投机取巧,只能逐层尝试,否则在任何一层上蛋碎了,我们都不能准确得出最高安全楼层。

一个鸡蛋的情况大致如此。虽然答案简单粗暴,但涉及的思路会对两个鸡蛋的情况有所启示。

两个鸡蛋的闹腾

两个鸡蛋的情况下,基本的想法也不难理解:

由于有两个鸡蛋可以用,所以第一个鸡蛋得用来确定一个比较大的范围。

但是心太黑了也不合适,步子迈得太大容易扯着蛋。

比如你一下子跑到50楼扔鸡蛋,看上去确实大量减少了工作量,但是蛋碎了怎么办呢?如果第一个蛋碎了,这时可以使用的蛋就只剩一个,而刚刚说了,只有一个蛋时我们没有选择,只能逐层去试。

这里体现了切分范围的思想,但同时体现了一个重要事实:
鸡蛋碎了比没碎要糟糕。

正因为这个事实的存在,因此在1-100层楼之前,我们第一个蛋的首次尝试应该向1这边(较可能不碎)倾斜,而不是向100那边(较可能碎)。

这样一个思路就出炉了:把100分成10个10层,第一个鸡蛋用来确认在哪个10层里,第二个鸡蛋用来确认具体层数。

具体来说就是,拿着第一个鸡蛋从第10层尝试,只要没碎就再上10层,直至碎了或者爬到楼顶,这样确定了十位数的范围。然后再用第二个鸡蛋逐层尝试。

比如第一个鸡蛋:

第10层扔下没碎,

第20层扔下没碎,

第30层扔下没碎,

第40层扔下碎了;

那么就拿第二个鸡蛋从31层至39层开始依次逐层尝试,直至排查出最高安全楼层为止。

这个思路已经基本成型,也比较接近答案了,只需要最后一点调整。

最后的雕琢

上面这个10*10的思路比逐层尝试已经有显著改进。

它的基本思路是,将100层切分成两个维度,由两个鸡蛋分别控制一个维度。

换言之,是将100层切分成若干个区块,由第一个鸡蛋确定最高安全楼层所属的区块,再由第二个鸡蛋逐层确定其具体的位置。大致思路如下:

每十个楼层,算作一个区块的话

 1-10         —— 区块111-20        —— 区块221-30        —— 区块3……

但仔细思考的小伙伴可以发现,这个答案还有问题。

比如如果鸡蛋最高安全楼层为16或者96,用刚刚那个思路的话,这两种情况的总尝试次数并不一样:最高安全楼层为16时,第一个鸡蛋试了2次就定位了区块;而最高安全楼层为96时,第一个鸡蛋试了10次才定位了区块。虽然在区块内部的第二个鸡蛋的逐层尝试是一样的,但96层对应的总尝试次数就多得太多了。

原因就是10*10的区块均匀划分对大数不利。

因为碎和不碎这两种状态是不对称的,所以第一个鸡蛋的尝试的过程只能从小数逐渐尝试到大数,而不能反着来。所以均匀划分区块对大数是不公平:同样在每个区块里的第6层,第一个鸡蛋走到十位数以9开头的区块里需要的次数太多了。

明白了这个缺陷,也就知道了改进的基本思想:还是要对100找出一种二维区块划分,但不是均匀划分。对于比较小的楼层部分,其包含的楼层范围可以适当多;越向大数部分走,其包含的楼层范围越来越小。从下往上,每一个区块内所含楼层递减。

对于最高安全楼层比较低的情况,第一个鸡蛋试的次数少;所以最高安全楼层比较高的情况,则让第二个鸡蛋试的次数少。用第二个鸡蛋的尝试次数的减少来弥补第一个鸡蛋需要尝试的次数的递增,使两个鸡蛋在不同维度上的尝试次数达到一种微妙的平衡。

按照这个思路,要把上面那个均匀的区块切分改进如下:

1,2,3,4……,x   ——区块1
x+1,x+2,……      ——区块2
……
91,92,93,94   ——区块n-3
95,96,97,     ——区块n-2
98,99,        ——区块n-1
100,          ——区块n

由于每个区块逐次递减1,所以最后的区块里包含1个楼层;相应地,区块总数也可能会变化,不再是10个区块。

那么这里的x和n会是多少呢?

最后一个区块里包含1个楼层,

倒数第二个包含2个楼层,

倒数第三个包含3个楼层,

继续,各区块包含的楼层是4,5,6,……

于是问题转变为,到包含多少个楼层的时候,100个楼层全部分配完?

由于1+2+3+……+13=91,

而1+2+3+……+14=105,

就是说从1开始累加,加到14时,总和第一次大于100:

所以上图里的x是14。

答案揭晓

注意,从14加到1的和是105,还多了5,多的部分可在各区块内分配扣减,不同的扣减方法会对应不同楼层分布的答案。

比如把原来10*10的划分进行如下调整:

10,  10,  10,  10,  10,  10,  10,  10,  10,  10,
14,  13,  12,  11,  10, 9,  8, 7,  6,  5,  4,  1,

这样对应的答案就是:

先上14楼把第一个鸡蛋扔下去。

没碎,则上(14+13=)27楼再试。

还没碎,上(27+12=)39楼试。

还没碎,上(39+11=)50楼试。

还没碎,上(50+10=)60楼试。

还没碎,上(60+9=)69楼试。

还没碎,上(69+8=)77楼试。

还没碎,上(77+7=)84楼试。

还没碎,上(84+6=)90楼试。

还没碎,上(90+5=)95楼试。

还没碎,上(95+4=)99楼试。

还没碎,上100楼试。

如果中间任何一次鸡蛋碎了,则用第二个鸡蛋从前一次尝试的下一层开始逐层试。如果14楼的第一次尝试就碎了,那么用第二个鸡蛋从1楼开始逐层试。

这时我们来检查一下,当最高安全楼层为几个比较讨厌的特殊值最后的边界值时,分别需要尝试的次数:

——最高安全楼层为13时,第一个鸡蛋第1次就碎了。第二个鸡蛋从1逐层试到13要试13次,一共试了1+13=14次。

——最高安全楼层为26时,第一个鸡蛋试了14,27,在第2次碎了。第二个鸡蛋从15逐层试到26,要试12次,一共是2+12=14次。

——最高安全楼层为38时,第一个鸡蛋试了14,27,39,在第3次碎了。第二个鸡蛋从28试到38,要试11次,一共是3+11=14次。

……………………

——最高安全楼层为98时,第一个鸡蛋试了14,27,39,50,60,69,77,84,90,95,99,在第11次碎了。第二个鸡蛋从96试到98试3次,一共是11+3=14次。

——最高安全楼层为99时,第一个鸡蛋试了14,27,39,50,60,69,77,84,90,95,99,100,在第12次碎了。第二个鸡蛋不用试。一共是12次。

——最高安全楼层为100时,第一个鸡蛋试了14,27,39,50,60,69,77,84,90,95,99,100,最后也没碎,第二个鸡蛋还是不用试。一共也是12次。

最后的两个情况是边界的特殊情况,之前的各次尝试都已经是最糟糕的情况,其他的所有情况总尝试次数都会小于14:

比如最高安全楼层是24,第一个鸡蛋试了14,27,在第2次碎了。第二个鸡蛋从15到25试11次,一共是2+11=13次。

再比如最高安全楼层为71时,第一个鸡蛋试了14,27,39,50,60,69,77,在第7次碎了。第二个鸡蛋从70到72试3次,一共是7+3=10次。

综上,问题解决:第一个鸡蛋依次试14,27,39,50,60,69,77,84,90,95,99,100。中间任何一次破碎了,就从上一次的下一层开始用第二个鸡蛋逐层尝试,直至第二个鸡蛋也破碎为止。

用这个方法,总次数一定不超过14次:当最高安全楼层越来越高时,第一个鸡蛋试的次数越来越多,但第二个鸡蛋试的次数越来越少,两者始终维持着一种平衡。

余 音

1、14到底怎么算出来的?

——从x递减到1的数列要累加超过100,所以14其实是满足x(x+1)/2>100的最小正整数。

更进一步说,如果总楼高不是100而是n,则解不等式x(x+1)/2>n得到的最小正整数x就是用第一个鸡蛋首次尝试所迈开的“步长”,也是使用正确方法所得到的最少尝试次数。

2、本题解答唯一吗?

——如前所述,14这个最少尝试次数是满足x(x+1)/2>100的最小正整数,这是唯一的。但14递减到1的数列累加为105,比100多出的部分可在各个区域任意分配,这样对应具体的楼层分布方案会有所不同,但都可行。比如用第一个鸡蛋依次尝试13,25,36,46,55,64,72,79,85,90,94,97,99,100就是另一个正确解答,其最少尝试次数也是14。

3、思考的难点在哪里?

——难点在于想到用两个鸡蛋分别控制两个维度,并且两个维度之间要保持微妙的平衡,剩下的思考过程就比较自然了。但是涉及到与具体的数打交道时还是要细心,尤其是在处理边界情况时要格外小心。

LeetCode 887. 鸡蛋掉落

你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。

每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

你的目标是确切地知道 F 的值是多少。

无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?

示例 1:

输入:K = 1, N = 2
输出:2
解释:
鸡蛋从 1 楼掉落。如果它碎了,我们肯定知道 F = 0 。
否则,鸡蛋从 2 楼掉落。如果它碎了,我们肯定知道 F = 1 。
如果它没碎,那么我们肯定知道 F = 2 。
因此,在最坏的情况下我们需要移动 2 次以确定 F 是多少。
示例 2:

输入:K = 2, N = 6
输出:3
示例 3:

输入:K = 3, N = 14
输出:4

提示:

1 <= K <= 100
1 <= N <= 10000

PS:

 * 鸡蛋掉落,谷歌面试题, * 有 K 个鸡蛋,有 N 层楼,用最少的操作次数 F 检查出鸡蛋的质量。** 思路:* 本题应该逆向思维,若你有 K 个鸡蛋,你最多操作 F 次,求 N 最大值。** dp[k][f] = dp[k][f-1] + dp[k-1][f-1] + 1;//这里就当成当前这一层所能决定的层数为鸡蛋没摔的层数+鸡蛋摔了的层数+当前这一层* 解释:* 0.dp[k][f]:如果你还剩 k 个蛋,且只能操作 f 次了,所能确定的楼层。* 1.dp[k][f-1]:蛋没碎,因此该部分决定了所操作楼层的上面所能容纳的楼层最大值* 2.dp[k-1][f-1]:蛋碎了,因此该部分决定了所操作楼层的下面所能容纳的楼层最大值* 又因为第 f 次操作结果只和第 f-1 次操作结果相关,因此可以只用一维数组。
class Solution {//二维数组的解法
//    public int superEggDrop(int K, int N) {//         if (N == 1) {//             return 1;
//         }
//         int[][] f = new int[N + 1][K + 1];
//         for (int i = 1; i <= K; ++i) {//             f[1][i] = 1;
//         }
//         int ans = -1;
//         for (int i = 2; i <= N; ++i) {//             for (int j = 1; j <= K; ++j) {//                 f[i][j] = 1 + f[i - 1][j - 1] + f[i - 1][j];
//             }
//             if (f[i][K] >= N) {//                 ans = i;
//                 break;
//             }
//         }
//         return ans;
//     }//一维数组的解法public int superEggDrop(int K, int N) {int[] dp = new int[K + 1];int ans = 0;    // 操作的次数while (dp[K] < N){for (int i = K; i > 0; i--) // 从后往前计算dp[i] = dp[i] + dp[i-1] + 1;ans++;}return ans;}}

经典面试题扔鸡蛋(Google面试题附带LeetCode例题)相关推荐

  1. 谷歌公司经典面试题扔鸡蛋的详细解读(一)

    文章目录 题目:扔鸡蛋问题 方法一: 方法二: 方法三: 方法三进阶:假设法 总结: 首先说一下大概的题目 题目:扔鸡蛋问题 有2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬度.比如鸡蛋在第9层没 ...

  2. 谷歌公司经典面试题扔鸡蛋的详细解读—动态规划(二)

    首先要说的是到底啥是动态规划? 那么,怎样找到状态转移方程式呢? 状态转移方程式有了,如何计算出这个方程式的结果呢? 代码如何实现? 如何优化呢? --------------– 上一篇博客中咦非常通 ...

  3. 经典谷歌面试题-扔鸡蛋问题

    假如有100层楼,总共有2个鸡蛋.需要多少次才能试探出临界点,比如,在第三层扔下去,不碎:在第四层扔下去,碎了,那第三层和第四层就是临界点.  如果之前没准备过的话,大概第一个想到的就是二分法. 1. ...

  4. 漫画:经典谷歌面试题“扔鸡蛋”,看看你会做吗?

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

  5. 扔玻璃球 [ Google面试题 ]

    这是一道 Google 面试题,考察的是对于 粗调 和 精调 工程思维 对于扔玻璃球国内也叫扔鸡蛋. ta不用您有什么基础,只需要一个基本工程思维. 粗调和精调,这个已是统计学里最优法,所以不用担心复 ...

  6. 经典谷歌面试题:高楼扔鸡蛋

    经典谷歌面试题:高楼扔鸡蛋 存在某T层高楼,在该高楼中存在这样的一层,在该层之下的所有楼层扔鸡蛋,鸡蛋摔到地上都不会碎,还可以继续扔:在该层及该层之上的所有楼层,扔下鸡蛋都会摔碎. 目前手里有两个鸡蛋 ...

  7. 经典算法面试题:高楼扔鸡蛋

    点击上方蓝字 关注我,涨知识 01 PART 扔鸡蛋实验 有一栋100层的楼,和2个坚硬的鸡蛋,从楼上扔下鸡蛋,鸡蛋会在大于某一层刚好开始碎,那最少几次能测出鸡蛋能承受的最大楼层呢? 如果从第50层扔 ...

  8. 两个鸡蛋--一道Google面试题

    前两天翻译Python文档翻译到手软.今天不想翻译了,上网闲逛,在http://programming.reddit.com/ 上看到一道有趣的题目,据说是清华东门某家公司的面试题.原文地址http: ...

  9. 谷歌面试题之扔鸡蛋的问题(蓝桥杯摔手机的问题)

    来自一个古老的公众号(摔手机就是根据扔鸡蛋过来的) 吐个槽先 正如昨天所说,这道题据说它最早见于谷歌的某次面试,由于题目表述容易,而解答相对麻烦,于是被很多人采用,广泛见于一些算法.规划的面试里. 要 ...

最新文章

  1. pandas -表的横向合并 纵向合并
  2. 【NOI2015】软件包管理器
  3. 盘点最重要的7个Python库
  4. 【差分隐私的Advanced composition到底是什么?】差分隐私系统学习记录(四)
  5. OpenShift 4 Tekton - Katacoda的Tekton Pipeline入门示例
  6. 设计模式教程(Design Patterns Tutorial)笔记之一 创建型模式(Creational Patterns)...
  7. Hexo 简明入门教程(一)
  8. 碱性干电池的内阻测试方法_电池内阻怎么测
  9. 如何提高计算机软件的性能,如何提高计算机性能?
  10. DOM SAXReader
  11. 【Scratch】青少年蓝桥杯_每日一题_12.01_角色装扮
  12. linux系统修改Mac地址
  13. Vue实战篇三十四:给新闻WebApp加入模拟注册登录功能
  14. 诸葛智能荣登《2022中国企业数智化转型升级创新服务企业》榜单!
  15. STM32F103的AD采样非线性问题
  16. 工作笔记先-xw-server
  17. 当前主要的常用的PHP环境部署套件比较
  18. 【无标题】学习贪吃蛇代码
  19. 在移动端页面进行调试
  20. 最实用的简历模板之一:QQ邮箱免费简历模板

热门文章

  1. freeSwitch DISA实现
  2. 升级AndroidStuido 4.2后 Gradle Tasks 不见了?
  3. T-SQL 错误状态
  4. 够迫履门夹钾灼敛墒套谮姑韩立对墨大夫一年后是否真的信守承诺,很是怀疑,若真是像对方所说
  5. 利用CEB-fib Model Code计算混凝土结构疲劳的方法
  6. iOS常用国外网站清单
  7. 鸿蒙系统适配机型测试,要来了! 华为鸿蒙系统进入最后测试阶段, 适配机型多达百万...
  8. 关于计算机春联PPT,春节祝福专题-春联.ppt
  9. 百度人脸识别API调用(人脸搜索)Java实现
  10. 《Swf文件的那些事》—as函数跨平台的交互详解