leetcode困难887鸡蛋掉落

Posted qq_40707462

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode困难887鸡蛋掉落相关的知识,希望对你有一定的参考价值。


思路1:递归

N :使用一栋从 1 到 N 共有 N 层楼的建筑
F :满足 0 <= F <= N ,任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破(F 比 N 多一个 0 层)

问题转换:

将问题从: N 个楼层,有 K 个蛋,求最少要扔 T 次,才能保证当 F 无论是 0 <= F <= N 中哪个值,都能测试出来
转变为:有 K 个蛋,扔 T 次,求可以确定 F 的个数,然后得出 N 个楼层

  • 1个蛋 T 次机会,或 K 个蛋 1 次机会,只可以确定出 T + 1 个 F(去掉0层,即最多可以确定第 T 楼)
  • 其他情况时,递归。【蛋碎了减 1 个,机会减 1 次】 + 【蛋没碎,机会减 1 次】

比如: N = 2 层楼(只需要K(1) 个蛋,扔T(2)次)
在 1 层扔,碎了,F < 1,所以确定 F = 0
在 1 层扔,没碎,但在 2 层扔,碎了, F >= 1 && F < 2,所以确定 F = 1
在 2 层扔,没碎,F >= 2,所以确定 F = 2

比如:K(2) 个蛋,T(3)次机会

  • 第一次应当从 3 层仍,最坏情况碎了,剩下 K(1) 个蛋,T(2)次机会,可以判断一二层的情况;
  • 第二次从 5 层扔,碎了的话,剩下 K(1) 个蛋,T(1)次机会,也可以判断 T+1=2 个楼层的情况,即三四层情况
  • 如果还没碎,剩下 K(2) 个蛋,T(1)次机会,只能从 6 层扔,判断T+1=2 个楼层的情况,即五六楼情况
class Solution {
    public int superEggDrop(int k, int n) {
        int T=1;
        while(calF(k,T)<n+1) T++;
        return T;
    }

    public int calF(int K,int T){
        if (T == 1 || K == 1) return T + 1;
        return calF(K - 1, T - 1) + calF(K, T - 1);
    }
}

优化:动态规划,避免递归重复计算
左边是碎的那段 长度是dp[k][T - 1]
右边是没碎的那段 长度是dp[k-1][T - 1] 因为已经碎了一个了
中间是我选定扔的楼层 是1

class Solution {
    public int superEggDrop(int k, int n) {
        int[][]dp=new int[k+1][10000];
        int T=0;
        while(dp[k][T]<n){
            T+=1;
            for(int i=1;i<=k;i++){
                dp[i][T]=1+dp[i-1][T-1]+dp[i][T-1];
            }
        }
        return T;
    }
}

再优化:dp[i][T]=1+dp[i-1][T-1]+dp[i][T-1];里的[T-1]是相同的,所以可以忽略这一维,如果采用k倒着从大到小计算 就可以只存一行的dp[k] 直接原地更新dp[k] 不影响后续计算

class Solution {
    public int superEggDrop(int k, int n) {
        int[]dp=new int[k+1];
        int T=0;
        while(dp[k]<n){
            T+=1;
            for(int i=k;i>0;i--){
                dp[i]=1+dp[i-1]+dp[i];
            }
        }
        return T;
    }
}

以上是关于leetcode困难887鸡蛋掉落的主要内容,如果未能解决你的问题,请参考以下文章

[LeetCode] 887. 鸡蛋掉落

LeetCode887鸡蛋掉落——dp

力扣第887题 鸡蛋掉落

[leetcode] 鸡蛋掉落 Google面试题 dp

鸡蛋掉落问题解析

leetcode 887. Super Egg Drop