最新要闻
- 【当前热闻】男子新买百万奔驰被朋友借走撞烂:保险拒赔!最终结局意外
- 江西南昌县发生重大交通事故 造成17人死亡22人受伤
- 【环球新视野】特斯拉车价降至史上最低!才开30公里车主委屈:销售催提车
- 每日视点!成都车主“0元购”引热议 此前还有维权车主要平分特斯拉股权
- 最资讯丨国产特斯拉大降价后车主维权 能拿到四项补偿?回应来了
- 电动救生圈亮相CES:时速15公里 续航6公里
- 《三体》动画播放量破3亿!豆瓣跌破5分 差评率高达83%
- 环球百事通!8K电视凉了?CES 2023新品少的可怜:销量份额0.15%不忍直视
- 实时焦点:安卓刷机时代落幕!开源ROM魔趣创始人宣布删库跑路
- 两款40系新卡RTX 4070/4060 Ti来了:没有最便宜 只有更便宜!
- 红到冒泡的《鹅鸭杀》 我玩起来是一点兴趣都没有
- 上次还是旧石器时代!5万年一遇彗星将造访地球:肉眼或可见
- 腾讯推出“游戏锁”功能:再也不怕《王者荣耀》号被盗了
- 【世界快播报】AMD、NVIDIA显卡越来越贵 Intel成了救星:2000元档唯一新卡
- 5199元起 红魔8 Pro+明天开卖:无刘海无挖孔 观感明显好于iPhone 14 Pro
- 【环球快播报】“爱妻”来了!理想L7的二排空间有多大?史无前例的“皇后座”感受下
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
LeetCode 887. 鸡蛋掉落-题解分析
题目来源
887. 鸡蛋掉落
题目详情
给你 k
枚相同的鸡蛋,并可以使用一栋从第 1
层到第 n
层共有 n
层楼的建筑。
已知存在楼层 f
,满足0 <= f <= n
,任何从 高于f
的楼层落下的鸡蛋都会碎,从 f
楼层或比它低的楼层落下的鸡蛋都不会破。
(资料图片)
每次操作,你可以取一枚没有碎的鸡蛋并把它从任一楼层 x
扔下(满足1 <= x <= n
)。如果鸡蛋碎了,你就不能再次使用它。如果某枚鸡蛋扔下后没有摔碎,则可以在之后的操作中 重复使用这枚鸡蛋。
请你计算并返回要确定 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 <= 104
题解分析
首先看到本题的题眼即“最小操作次数”就能大概猜到本题需要使用动态规划的方法进行求解。仔细看一下题目的描述,其实如果自己手动计算的话会发现没有什么特殊的规律,而且很难列举出每一种情况。
本题的解题关键在于如何在鸡蛋碎了时做出选择,我们知道,如果鸡蛋在某一层碎了,那就说明边界条件必定在该层以下,后续需要往下扔鸡蛋;如果鸡蛋在该层没碎,那说明现在还没达到边界条件,后续需要继续往上走,在更高楼层扔鸡蛋。
解法一
这里还是使用动态规划的思想来设计状态转移,我们定义dp[i][j]表示i个鸡蛋,j层楼,最坏的情况下最少需要扔多少次。状态转移方程如下:
\[d p(i, j)=\min _{0<=i<=N}\{\max \{d p(i-1, j-1), d p(i, N-j)\}+1\}\]上述dp[i-1][j-1]表示鸡蛋在第j层碎了,此时需要往下走,因为鸡蛋碎了,所以鸡蛋个数减一;dp[i][n-j]表示鸡蛋在第j层没碎,此时需要往上走,而往上可以走的层数只剩n-j层了,鸡蛋个数不变。
基于上述思路,一种基于递归和动态规划的解法如下:
class Solution { int mins = -0x3f3f3f3f; int[][] mem; public int superEggDrop(int k, int n) { // dp[i][j]表示i个鸡蛋,j层楼,最坏的情况下最少需要扔多少次 // dp[i][j] = min(1<=j<=n)(max(dp[i-1][j-1], dp[i][n-j]) + 1); mem = new int[k+1][n+1]; for (int i=0; i<=k; i++) { Arrays.fill(mem[i], mins); } return dp(k, n); } public int dp(int k, int n) { // 只有一个鸡蛋,必然最少要扔n次 if (k == 1) { return n; } // 0层楼,无论多少个鸡蛋,不用扔 if (n == 0) { return 0; } if (mem[k][n] != mins) { return mem[k][n]; } int res = 0x3f3f3f3f; for(int j=1; j<=n; j++) { res = Math.min(res, Math.max(dp(k-1, j-1), dp(k, n-j)) + 1); } mem[k][n] = res; return res; }}
很遗憾的是,上述解法会导致超时,尽管使用了备忘录来进行递归剪枝,然而在每层递归中,还是需要从1到n遍历每层楼来进行状态的转移,这会极大增加算法的时间复杂度。
其实,我们可以仔细观察dp[i-1][j-1]以及dp[i][n-j]这两个表达式,当我们遍历j的时候,我们其实可以发现dp[i-1][j-1]其实是随着j的增大而增大的。这是因为随着楼层的增加,最小的操作次数必然增加了,因为需要尝试更多次才能确定边界。同理,dp[i][n-j]会随着j的增加而减少。
基于上述观察,我们其实可以发现,dp[i-1][j-1]和dp[i][n-j]其实分别单调递增和单调递减,这两者一定会有一个交点,而且这个交点就是边界条件,也就是答案。因此,我们可以使用二分法来加速算法运行,通过dp[i-1][j-1]以及dp[i][n-j]来判断二分的边界。
使用二分法优化的解法如下:
class Solution { int mins = -0x3f3f3f3f; int[][] mem; public int superEggDrop(int k, int n) { // dp[i][j]表示i个鸡蛋,j层楼,最坏的情况下最少需要扔多少次 // dp[i][j] = min(1<=j<=n)(max(dp[i-1][j-1], dp[i][n-j]) + 1); mem = new int[k+1][n+1]; for (int i=0; i<=k; i++) { Arrays.fill(mem[i], mins); } return dp(k, n); } public int dp(int k, int n) { // 只有一个鸡蛋,必然最少要扔n次 if (k == 1) { return n; } // 0层楼,无论多少个鸡蛋,不用扔 if (n == 0) { return 0; } if (mem[k][n] != mins) { return mem[k][n]; } int res = 0x3f3f3f3f; int low = 1, high = n; while (low <= high) { int mid = low + (high - low) / 2; int below = dp(k-1, mid-1); // 在第j层碎了 int above = dp(k, n - mid); // 在第j层没碎 if (below > above) { high = mid - 1; res = Math.min(res, below + 1); } else { low = mid + 1; res = Math.min(res, above + 1); } } mem[k][n] = res; return res; }}
解法二
在第一种解法中,我们定义的状态为dp[i][j],它的含义是当前有i个鸡蛋,j层楼,最坏的情况下最少需要扔多少次。其实,动态规划并不是只有一种确定的解法,随着状态定义的不同会有很多截然不同的解法。
在这里,我们可以重新来定义动态规划的状态,假设dp[i][j]表示i个鸡蛋,扔j次可以确定的最高楼层。也就是持有i个鸡蛋,允许最多扔j次,最高用来确定的楼层高度。
根据上述定义,我们可以列出动态转移方程如下:
\[dp[i][j] = dp[i][j-1] + dp[i-1][j-1] + 1\]其中,dp[i][j-1]表示在某层扔了一个鸡蛋但没碎,此时需要往上走,这时可以扔的次数-1,鸡蛋总数不变。结果可以表示为该层楼上的层数;dp[i-1][j-1]表示在某层扔了鸡蛋但是碎了,此时需要往下走,这时可以扔的次数-1,鸡蛋总数也-1(因为碎了一个)。结果表示为该层楼下的层数。
class Solution { public int superEggDrop(int k, int n) { // dp[i][j]表示i个鸡蛋,扔j次可以确定的楼层 // dp[i][j] = dp[i][j-1] + dp[i-1][j-1] + 1; // dp[i][j-1]表示在某层扔了一个鸡蛋但没碎,此时需要往上走,这时可以扔的次数-1,鸡蛋总数不变。结果可以表示为该层楼上的层数 // dp[i-1][j-1]表示在某层扔了鸡蛋但是碎了,此时需要往下走,这时可以扔的次数-1,鸡蛋总数也-1(因为碎了一个)。结果表示为该层楼下的层数 int[][] dp = new int[k+1][n+1]; int j=0; while(dp[k][j] < n) { j++; for (int i=1; i <= k; i++) { dp[i][j] = dp[i][j-1] + dp[i-1][j-1] + 1; } } return j; }}
上述解法是一种很规范的二维动态规划的写法,这种二维动态规划通常可以进行空间优化写成一维动态规划。这里要改写成一维动态规划,关键是需要使用一个变量来记录之前的状态避免被后续的遍历所覆盖。具体的实现如下代码所示:
class Solution { public int superEggDrop(int k, int n) { // dp[i][j]表示i个鸡蛋,扔j次可以确定的楼层 // dp[i][j] = dp[i][j-1] + dp[i-1][j-1] + 1; // dp[i][j-1]表示在某层扔了一个鸡蛋但没碎,此时需要往上走,这时可以扔的次数-1,鸡蛋总数不变。结果可以表示为该层楼上的层数 // dp[i-1][j-1]表示在某层扔了鸡蛋但是碎了,此时需要往下走,这时可以扔的次数-1,鸡蛋总数也-1(因为碎了一个)。结果表示为该层楼下的层数 int[] dp = new int[k+1]; int j=0; while(dp[k] < n) { j++; int pre = 0; for (int i=1; i <= k; i++) { int temp = dp[i]; dp[i] = dp[i] + pre + 1; pre = temp; } } return j; }}
参考
https://zhuanlan.zhihu.com/p/92288604
LeetCode 887. 鸡蛋掉落-题解分析
【当前热闻】男子新买百万奔驰被朋友借走撞烂:保险拒赔!最终结局意外
江西南昌县发生重大交通事故 造成17人死亡22人受伤
【环球新视野】特斯拉车价降至史上最低!才开30公里车主委屈:销售催提车
热讯:java多线程知识点总结
今日热门![Docker] 将容器打包成镜像、镜像分层机制详解
每日视点!成都车主“0元购”引热议 此前还有维权车主要平分特斯拉股权
环球速看:学习笔记——Maven
最资讯丨国产特斯拉大降价后车主维权 能拿到四项补偿?回应来了
电动救生圈亮相CES:时速15公里 续航6公里
《三体》动画播放量破3亿!豆瓣跌破5分 差评率高达83%
环球百事通!8K电视凉了?CES 2023新品少的可怜:销量份额0.15%不忍直视
实时焦点:安卓刷机时代落幕!开源ROM魔趣创始人宣布删库跑路
两款40系新卡RTX 4070/4060 Ti来了:没有最便宜 只有更便宜!
红到冒泡的《鹅鸭杀》 我玩起来是一点兴趣都没有
上次还是旧石器时代!5万年一遇彗星将造访地球:肉眼或可见
最新:使用KVM克隆用于Oracle DB的主机
腾讯推出“游戏锁”功能:再也不怕《王者荣耀》号被盗了
【世界快播报】AMD、NVIDIA显卡越来越贵 Intel成了救星:2000元档唯一新卡
5199元起 红魔8 Pro+明天开卖:无刘海无挖孔 观感明显好于iPhone 14 Pro
焦点速讯:AcWing395. 冗余路径
播报:在linux中通过虚拟机转发流量访问内网
每日热闻!分享2023年最新的15种JavaScript 速记技巧 【终极秘籍】
世界观点:express实现批量删除和分页
天天观点:Docker-Compose容器编排
Linux笔记03: Linux常用命令_3.4文件和目录共用命令
Python+matplotlib实现折线图的美化
当前快讯:vue-router的使用
全球最资讯丨Unity初始界面设计与人物移动代码
学习笔记——书城项目之“我的订单”功能
环球百事通!一些学习编程的优质网站
学习笔记——书城项目第六阶段之去结账功能的准备工作、去结账功能的实现
【环球快播报】“爱妻”来了!理想L7的二排空间有多大?史无前例的“皇后座”感受下
精彩看点:Docker轻量级可视化工具Portainer
热点评![概率论与数理统计]笔记:2.5 随机变量函数的分布
全球简讯:express学会CRUD
当前速递!影像机皇预定!小米13 Ultra堆料惊人:四颗5000万像素主摄
今日报丨B站地区限制破解方法
【环球报资讯】日本60岁宅男看动漫被打断对父母下狠手 啃老30年:网友吐槽二次元危害大
Spring IOC官方文档学习笔记(七)之Bean Definition继承
焦点快报!丙种球蛋白被炒到上万元 真的需要囤一点吗?
20款理想ONE新功能上线:支持3.5kW外放电、配套设备仅2999元
当前快讯:一种inlineHook检测方案
今日快讯:拖死锤子 罗永浩回应遭郑刚炮轰获圈内人士力挺:喜欢乱搞小三关系
国产屏真香!苹果也喜欢:iPhone 15/15 Plus要用京东方屏
一加11砍掉8GB丐版!员工:一加用户都喜欢大内存版本
HTML超文本标记语言1
环球快资讯丨复刻iPhone 14 Pro!乐视手机S1 Pro入网:搭载国产芯 这真不卡
世界速读:Mini LED屏加入高端笔记本阵营!硬刚OLED
环球观焦点:NOI2003 文本编辑器 题解
世界热讯:特斯拉股东要求董事会做好接班准备:以防失去马斯克
全球观察:投资人郑刚炮轰罗永浩拖死了锤子 罗永浩回应:严重失实
能流畅用4年不卡的骁龙8系手机来了!一加11下周首销:3999元
热讯:老雷筹拍《角斗士2》
靳东宋佳主演电视剧《纵有疾风起》热播:moto razr折叠屏抢镜
即时:普及150W秒充 真我GT Neo3手机12GB大内存版直降600元
天天速看:女子表白领导被拒后每天在公司摸鱼 还免被裁引热议:网友吐槽道德绑架
[Docker]使用Docker开启一个MariaDB服务并在宿主机里访问服务
当前速读:小鹏P7喜提开年首次OTA:新增“神仙级”NGP车道定位功能
极其反常!欧洲多国冬天像夏天:多处滑雪胜地闹雪荒
专业鼻腔护理 海元素生理性盐水鼻腔喷雾器60ml 12.23元包邮
特斯拉再降价!Model3创历史新低:你还等“Model 2”吗?
专家建议不要生吃可生食鸡蛋:有健康风险
全球微资讯!以小见大:由低代码的发展,窥企业数智化转型之路
关注:阿凡达2回本!卡梅隆确认拍续集:剧透《阿凡达3/4/5》剧情/进度
【天天报资讯】e平台3.0首车 比亚迪海豚12月热销2.6万:本田飞度彻底被打趴
最新消息:投资人郑刚炮轰罗永浩:拖死锤子、不懂感恩,将联合发起回购
宝岛眼镜旗舰店抄底:镜框+防蓝光近视镜片99元包邮
开五天 一天降一万老车主泪奔维权!特斯拉国产车降价为冲量 拒绝补偿
当前快讯:全球变暖加剧:专家称本世纪末全球三分之二冰川或消失
全球简讯:21岁网红庄慕卿车祸身亡 逆向行驶还翘头致两车相撞4人遇难:网友称禁止摩托车
环球微速讯:Codeforces Round #842 (Div. 2) A-E
焦点速读:使用KVM创建OEL虚拟机
别只用来发电了 太阳能制氢突破!10倍效率 成本还更低
全球即时看!全球首个全功能无线底座问世:干掉线缆 满足4K/60Hz带宽
今头条!豆瓣9.6分 《中国奇谭》凭什么让国漫再次封神?
全球要闻:Intel Arc A750显卡深入测试:性能RTX 3060、功耗RTX 3070
今日快讯:内网渗透-PTH&PTK&PTT哈希票据传递
天天微速讯:官方批准ARJ21国产客机改货机!最大运力10吨
天天微资讯!3.2K/165hz屏!联想第四代ThinkBook 16P发布: 配独特触点接口
每日速讯:汤姆·汉克斯谈好莱坞裙带关系:本就是家族产业
【天天播资讯】雷蛇灵刃18游戏本发布:18寸240Hz大屏、RTX 4090显卡替代台式机
特斯拉再降价 Model 3创历史新低!老车主亏哭了 山顶买车血亏6万
耗资两亿的《三体》 在《中国奇谭》面前毫无价值
内网信息收集
今日观点!day03-模块化编程
今日最新!vue中$children的理解
每日焦点!TCL华星展示最新带鱼屏模组:暗处无限接近0nit
天天热议:矿卡的阴影已经过去了 板卡一哥华硕率先表态:显卡库存已正常
全球观速讯丨遇到查酒驾猛打方向盘 结果巧了:直接一步到位
全球快资讯:无视油车 特斯拉Model Y成英国12月最畅销汽车
世界播报:售价超2万元!世界首款真无线电视现身CES:电池供电不插线
记录--微信调用jssdk全流程详解
最新:LaTeX 进阶语法
世界观热点:国人不再迷信日本车 日产2022年累计销量105万:同比暴跌超1/5
当前热讯:又见白菜价 梅捷2TB SSD硬盘到手554元(每GB不到3毛)
HTC Vive XR眼镜发布:双2K屏、配有可拆卸电池
最资讯丨四川一地再现土坑酸菜 工人用脚踩 网友无奈:眼不见为净
每日视讯:Redmi K60/K60 Pro对比拆解:做工用料良心!性价比刚刚的
【吐槽贴】项目经理的进阶日常:项目要收尾了,我却慌了