题目描述
给你 2 枚相同 的鸡蛋,和一栋从第 1
层到第 n
层共有 n
层楼的建筑。
已知存在楼层 f
,满足 0 <= f <= n
,任何从 高于 f
的楼层落下的鸡蛋都 会碎 ,从 f
楼层或比它低 的楼层落下的鸡蛋都 不会碎 。
每次操作,你可以取一枚 没有碎 的鸡蛋并把它从任一楼层 x
扔下(满足 1 <= x <= n
)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用 这枚鸡蛋。
请你计算并返回要确定 f
确切的值 的 最小操作次数 是多少?
题目分析
假设有 100 层楼,2 个鸡蛋,把 100 层楼分成 10 份。
第一个鸡蛋从第 10、20…100 层楼分别来扔,最坏的情况是在第 100 层破了,此时第一个鸡蛋扔了 10 次。
层数 | 次数 |
---|---|
10 | 1 |
20 | 2 |
30 | 3 |
… | … |
90 | 9 |
100 | 10 |
然后,第二个鸡蛋从 91 层开始扔,一直扔到 99 层,最坏情况是在 99 层破了,第二个鸡蛋扔了 9 次。所以,100 层的时候,两个鸡蛋最坏情况是扔 19 次。
但是,这种方法并不是最有的解法。
因为,第一个鸡蛋扔的次数是 1~10 次,第二个鸡蛋扔的次数也是 1~9 次,所以最好情况是扔 1 次(在第 1 层破了),最坏情况是扔 19 次(在 100 层破了),这样最好的情况和最坏的情况之间差距太大了。
**现在,我们希望第一个鸡蛋每多扔一次,第二个鸡蛋就少扔一次。**这样,能够保证最好的情况和最坏的情况,扔的次数都差不多。
那么,就不能够把 100 层楼等分了,而是要把间隔逐渐缩小。
第一个鸡蛋扔的次序是:
- 第 1 次:向上走 i 层楼(如果破了,第二个鸡蛋最多扔 i-1 次)
- 第 2 次:向上走 i-1 层楼(如果破了,第二个鸡蛋最多扔 i-2 次)
- 第 3 次:向上走 i-2 层楼(如果破了,第二个鸡蛋最多扔 i-3 次)
- …
- 第 i 次:向上走 1 层楼(如果破了,第二个鸡蛋则不用扔了)
这样,当第一个鸡蛋扔最后一次才碎的时候,第二个鸡蛋就不用扔了,所以两枚鸡蛋扔的次数都能够固定在 i 次。
那么,接下来计算 i 就可以了,公式如下:
所以,当楼层是 100 层是,应该这样扔:
第一个鸡蛋 | 第二个鸡蛋 |
---|---|
在 14 层扔(+14) | 1~13 层扔,扔 13 次 |
在 27 层扔(+13) | 15~26 层扔,扔 12 次 |
在 39 层扔(+12) | 28~38 层扔,扔 11 次 |
在 50 层扔(+11) | … |
在 60 层扔(+10) | … |
在 69 层扔(+9) | … |
在 77 层扔(+8) | … |
在 84 层扔(+7) | … |
在 90 层扔(+6) | … |
在 95 层扔(+5) | … |
在 99 层扔(+4) | … |
在 100 层扔(+1) | … |
这时候,最坏的情况是扔 14 次。
题目解答
/**
* @param {number} n
* @return {number}
*/
var twoEggDrop = function (n) {
let sum = 0;
let i = 1;
for (i = 1; i < n; i++) {
sum += i;
if (sum >= n) break;
}
return i;
};