前言
这个问题的灵感来自于上周关于SO的类似问题,在明确了真正的问题之前就被删除了。我认为这种变化是一个很好的问题,我想分享。
两个鸡蛋问题
可以找到详细的定义和解决方案here,但我会添加一个快速摘要:
定义
你有两个鸡蛋,可以进入
k
层楼。两个鸡蛋 是相同的。目的是找出最高楼层f*
当从那个楼层的窗户掉下来时,鸡蛋不会破裂。如果 鸡蛋掉落后不会破裂,它没有受损,可以掉落 再次。然而,一旦鸡蛋被打破,那就是那个鸡蛋。找到f*
的方法是什么(最少量的滴)?
解决方案
想法是从地板sqrt(k), 2*sqrt(k), 3*sqrt(k)... k
中放下第一个蛋。如果鸡蛋在地板i*sqrt(k)
处断裂,请使用第二个鸡蛋来测试(i-1)*sqrt(k)
和i*sqrt(k)-1
之间的剩余楼层。总的来说,这将导致最多2*sqrt(k)
次丢弃,因此复杂性将为O(sqrt(k))
。
只是为了完整性:有一种方法在最坏情况下具有较少的下降(详细信息可以找到here),但其具有与O(sqrt(k))
相同的复杂性
问题:无限/未知地板的两个蛋问题
现在假设您没有关于楼层数k
或k
无限的信息。是否有可能比仅f*
测试每个楼层更有效率O(f*)
?
换句话说:是否有一个高效的方法来删除运行时复杂度独立于k
的两个蛋,但只取决于答案f*
?
答案 0 :(得分:2)
有一种简单的方法具有O(sqrt(f *))复杂度。让你的第n步为n层,即检查楼层1,3(1 + 2),6(1 + 2 + 3)等。这样在第n步你就会在n *(n + 1)/ 2楼,你将在n = O(sqrt(f *))步骤中达到f *。
然后对于第二个鸡蛋,您将需要在第1阶段的最后一步中单步执行,这将添加另一个O(sqrt(f *))。
如果O(sqrt(k))对于已知k是最优的,则该方法在复杂性方面也必须是最优的。
答案 1 :(得分:-1)
对于两个蛋的无限问题的次优解是使用序列1, 2^2, 3^3,... ,i^2,...
并开始第二个边缘,其中第一个蛋剩下的最后一个值。因此,如果第一个边缘保持在n^2
,那么下一个边缘将最多执行2*n + 1 - 1
(从第一个开始减去1)测试,以在最坏的情况下给出3 * n
的总数{ {1}}。