前言
每天和你一起刷 LeetCode 每日一题~
LeetCode 启动!
题目:鸡蛋掉落-两枚鸡蛋
做题之前,突然有点想问:有鱼友每天刷力扣每日一题吗?
代码与解题思路
今天的题目 . . . 我也不知道怎么形容啦,还挺绕的,看了好一会儿才看明白题目想要我们求什么
题目给了两个鸡蛋,要我们使用这两个鸡蛋找到能让鸡蛋不碎的最高楼层,求出最小的操作次数,因为只有两个鸡蛋,所以要小心谨慎
假设第一个鸡蛋在 100 楼扔下来碎掉了,那想找出鸡蛋在第几层不会碎就得从 1 楼开始一层层往上找了,最坏的情况,就要一直从 1 楼摔倒 99 楼,总计操作 100 次
单看题目并没有什么思路,但是 . . . 观察示例二,能发现一些端倪:“则按照类似的方法从 34, 45, 55, 64, 72, 79, 85, 90, 94, 97, 99 和 100”,发现没有,从后往前看,100,99,97,中间的差值依照 -1,-2,-3 的规律递增,假设这就是最优的情况,那我们可以模拟出这样的谈心代码:
func twoEggDrop(n int) (ans int) {// 依照示例二的最优策略的规律i := 1for n > 0 {ans++n -= i i++}return ans
}
那有没有正常的解法呢?
动态规划也能实现:
func twoEggDrop(n int) int {// 用 DP 做f := make([]int, n+1)for i := 1; i <= n; i++ {f[i] = math.MaxIntfor j := 1; j <= i; j++ {f[i] = min(f[i], max(j, f[i-j]+1))}}return f[n]
}
我们设:dfs(i) 表示在一栋有 i 层楼的建筑中扔鸡蛋的最大操作次数
实际上就只有两种情况需要分类讨论:
1、鸡蛋碎了,那就只能从 1 楼开始一个个扔上来,需要 i 次
2、鸡蛋没碎,那就让 i 楼作为新的 1 楼继续计算,操作次数 + 1
枚举从在每层楼丢鸡蛋的情况,找出最小的操作数即可
对应到代码上
鸡蛋碎了的情况,对应 max 中的 j
鸡蛋没碎的情况,对应 f [i-j] + 1
for j := i 对应枚举在每层楼丢鸡蛋的情况。
每天进步一点点,我们明天不见不散~
可以和我刷一辈子的每日一题吗?
一题一题,积累起来就是一辈子。