Algorithm 鸡蛋掉落难题-需要建议
问题陈述 鸡蛋掉落指的是一类问题,在这些问题中,在不超过(低)个特定故障状态的情况下找到正确的响应非常重要。在一个玩具示例中,有一个楼层塔和一个装有理想鸡蛋的滴管。理想鸡蛋的物理特性是,如果它从地板或上面掉下来,它会破碎,如果它从地板或下面掉下来,它不会有任何损坏。问题是要找到一种策略,使得滴管可以在尽可能少的鸡蛋滴中确定地板。这个问题在现实世界中有很多应用程序,比如避免调用速度较慢的硬盘,或者尝试最小化缓存未命中,或者在数据库上运行大量昂贵的查询 当我们有N个鸡蛋和K个楼层时,下面的代码使用时间复杂度为O(N)的二次方程找到最小滴数Algorithm 鸡蛋掉落难题-需要建议,algorithm,Algorithm,问题陈述 鸡蛋掉落指的是一类问题,在这些问题中,在不超过(低)个特定故障状态的情况下找到正确的响应非常重要。在一个玩具示例中,有一个楼层塔和一个装有理想鸡蛋的滴管。理想鸡蛋的物理特性是,如果它从地板或上面掉下来,它会破碎,如果它从地板或下面掉下来,它不会有任何损坏。问题是要找到一种策略,使得滴管可以在尽可能少的鸡蛋滴中确定地板。这个问题在现实世界中有很多应用程序,比如避免调用速度较慢的硬盘,或者尝试最小化缓存未命中,或者在数据库上运行大量昂贵的查询 当我们有N个鸡蛋和K个楼层时,下面的代码使用
(function() {
var eggs = 3, floors = 2;
function findFloor(eggs, floors) {
if (eggs === 1 || floors === 0 || floors === 1) {
return floors;
}
var minDrops = Math.ceil((-1 + Math.sqrt(1 + (8 * floors))) / 2);
return Math.min(minDrops, findFloor(eggs - 1, minDrops));
}
console.log(findFloor(eggs, floors));
})();
我已经用一些测试用例进行了测试,但是有人能建议,这对所有场景都有效吗?我相信已知的是O(nlogk)
。以下是一些不匹配:
/*
W(n,k)=1+min{max(W(n− 1,x− 1) ,W(n,k)− x) ):x=1,2,…,k}
W(n,0)=0表示所有n>0,W(1,k)=k表示所有k。
*/
函数f(n,k){
如果(k==0&&n>0)
返回0;
如果(n==1)
返回k;
让最好=无限;
对于(设x=1;xNo),这并不总是产生正确的结果。您使用了以下公式:
但该公式仅在鸡蛋数量为2的情况下提供有意义的结果。请注意,鸡蛋的数量没有出现在公式中,只有楼层的数量(k)
反例
以4层和3个鸡蛋为例,你的函数返回2,但是如果这是正确的答案,那么你会在这两次尝试中选择哪一层
让我们从第三层往下扔:鸡蛋破了。然后从第一层往下扔:鸡蛋不破。现在我们不知道答案是第一层还是第二层。我们需要再扔一个鸡蛋才能确定
也许从2楼开始?:鸡蛋没问题。然后从4楼开始扔:鸡蛋破了。现在我们不知道答案是2楼还是3楼。我们需要再扔一个鸡蛋才能确定
所以,在最坏的情况下,我们至少要丢3个鸡蛋
结论
您的算法不正确。您提到的两篇文章有正确的实现(尽管有一些变量名的拼写错误)。它们在JavaScript中:
function getNumDropsRecursive(eggs, floors) {
if (eggs == 1 || floors == 0 || floors == 1) {
return floors
}
let minimum = Infinity;
for (let floor = 1; floor <= floors; floor++) {
minimum = Math.min(
minimum,
1 + Math.max(getNumDropsRecursive(eggs - 1, floor - 1),
getNumDropsRecursive(eggs, floors - floor))
)
}
return minimum;
}
function getNumDropsDP(eggs, floors) {
const numdrops = [
null,
[...Array(floors+1).keys()],
...Array.from(Array(eggs-1), _ => [0, 1])
];
for (let remainingEggs = 2; remainingEggs <= eggs; remainingEggs++) {
for (let choices = 2; choices <= floors; choices++) {
let minimum = Infinity;
for (let dropAt = 1; dropAt <= choices; dropAt++) {
minimum = Math.min(minimum,
1 + Math.max(numdrops[remainingEggs-1][dropAt-1],
numdrops[remainingEggs][choices-dropAt])
);
}
numdrops[remainingEggs][choices] = minimum;
}
}
return numdrops[eggs][floors];
}
函数getNumDropsRecursive(鸡蛋、地板){
如果(鸡蛋==1 | |地板==0 | |地板==1){
返回楼层
}
设最小值=无穷大;
对于(设楼层=1;楼层[0,1])
];
对于(让remaininggs=2;remaininggs)您使用的二次方程仅适用于2个鸡蛋的情况