递归思想解决leetcode之鸡蛋掉落

本文深入探讨了LeetCode上的超级丢蛋问题,通过递归和动态规划的方法,详细解析了如何确定最少的移动次数来找到特定楼层F。文章提供了基础和优化后的Go代码实现,帮助读者理解并解决这个复杂的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

你将获得 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-egg-drop
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这是一道困难的题目,推荐基础了解李永乐老师讲解的双蛋问题

思路来说,leetcode官方题解中的第三种解法反而最容易懂,所以本文就讲述一下我搞懂了的第三种方法。

已知
本题要求解的是N层楼使用K个鸡蛋,至少扔M次能找到临街楼层F。
又可解读为
用K个鸡蛋,操作T次,能找到最高的楼层是多少?需要满足最高楼层>=N。所以需要找出最小能满足f(T,K)>=N的T值
递归(动态规划)思考过程
关于f(T,K)怎么求,我们思考一下扔出一个鸡蛋,看看到底发生了什么:

如果鸡蛋没有碎,那么对应的是 f(T - 1, K),也就是说在这一层的上方可以有 f(T - 1, K) 层;

如果鸡蛋碎了,那么对应的是 f(T - 1, K - 1),也就是说在这一层的下方可以有 f(T - 1, K - 1)层。

因此我们就可以写出状态转移方程:

f(T, K) = 1 + f(T-1, K-1) + f(T-1, K)

边界条件为:当 T≥1 的时候 f(T, 1) = T,当 K≥1 时,f(1,K)=1。

那么T 最大可以达到多少?由于操作次数是一定不会超过楼层数的,因此 T≤N,我们只要算出在 f(N, K)内的所有 f 值即可。

go code

基础代码

func superEggDrop(K int, N int) int {
    if N==1 {
        return 1
    }
    var f [][]int
    for i:=0;i<=N;i++ {
        item := make([]int,K+1)
        f = append(f,item)
    }

    for i:=1;i<=K;i++ {
        f[1][i] = 1
    }
    ans := -1
    for i:=2;i<=N;i++ {
        for 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
}

进阶优化代码

func superEggDrop(K int, N int) int {
    times := 1
	for {
	    if getTimes(times, K) >= N {
			break
		}
		times ++
	}
	return times
}


func getTimes(times, eggCount int) int {
	if times == 1 || eggCount == 1{
		return times
	}
	return getTimes(times - 1, eggCount - 1) + 1 + getTimes(times - 1, eggCount)
}

总结

  • 遇到难题时,还是要回归到基础的一些思想
  • 比如本题学到的基础思想是递归
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值