[Leedcode][JAVA][第887题][鸡蛋掉落][谷歌面试][动态规划]

【问题描述】 [887. 鸡蛋掉落]

你将获得 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解答思路】

李永乐老师的视频:《复工复产找工作?先来看看这道面试题:双蛋问题》

image.png
image.png
image.png

方法:动态规划



image.png

1. 动态规划 -超时

时间复杂度:O(N^3) 空间复杂度:O(N^2)

import java.util.Arrays;public class Solution {public int superEggDrop(int K, int N) {// dp[i][j]:一共有 i 层楼梯的情况下,使用 j 个鸡蛋的最少实验的次数// 注意:// 1、i 表示的是楼层的大小,不是第几层的意思,例如楼层区间 [8, 9, 10] 的大小为 3,这一点是在状态转移的过程中调整的定义// 2、j 表示可以使用的鸡蛋的个数,它是约束条件,我个人习惯放在后面的维度,表示消除后效性的意思// 0 个楼层和 0 个鸡蛋的情况都需要算上去,虽然没有实际的意义,但是作为递推的起点,被其它状态值所参考int[][] dp = new int[N + 1][K + 1];// 由于求的是最小值,因此初始化的时候赋值为一个较大的数,9999 或者 i 都可以for (int i = 0; i <= N; i++) {Arrays.fill(dp[i], i);}// 初始化:填写下标为 0、1 的行和下标为 0、1 的列// 第 0 行:楼层为 0 的时候,不管鸡蛋个数多少,都测试不出鸡蛋的 F 值,故全为 0for (int j = 0; j <= K; j++) {dp[0][j] = 0;}// 第 1 行:楼层为 1 的时候,0 个鸡蛋的时候,扔 0 次,1 个以及 1 个鸡蛋以上只需要扔 1 次dp[1][0] = 0;for (int j = 1; j <= K; j++) {dp[1][j] = 1;}// 第 0 列:鸡蛋个数为 0 的时候,不管楼层为多少,也测试不出鸡蛋的 F 值,故全为 0// 第 1 列:鸡蛋个数为 1 的时候,这是一种极端情况,要试出 F 值,最少次数就等于楼层高度(想想复杂度的定义)for (int i = 0; i <= N; i++) {dp[i][0] = 0;dp[i][1] = i;}// 从第 2 行,第 2 列开始填表for (int i = 2; i <= N; i++) {for (int j = 2; j <= K; j++) {for (int k = 1; k <= i; k++) {// 碎了,就需要往低层继续扔:层数少 1 ,鸡蛋也少 1// 不碎,就需要往高层继续扔:层数是当前层到最高层的距离差,鸡蛋数量不少// 两种情况都做了一次尝试,所以加 1dp[i][j] = Math.min(dp[i][j], Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1);}}}return dp[N][K];}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/super-egg-drop/solution/dong-tai-gui-hua-zhi-jie-shi-guan-fang-ti-jie-fang/
2. 优化

image.png
image.png

时间复杂度:O(N^2logN) 空间复杂度:O(N^2)

import java.util.Arrays;public class Solution {public int superEggDrop(int K, int N) {// dp[i][j]:一共有 i 层楼梯的情况下,使用 j 个鸡蛋的最少仍的次数int[][] dp = new int[N + 1][K + 1];// 初始化for (int i = 0; i <= N; i++) {Arrays.fill(dp[i], i);}for (int j = 0; j <= K; j++) {dp[0][j] = 0;}dp[1][0] = 0;for (int j = 1; j <= K; j++) {dp[1][j] = 1;}for (int i = 0; i <= N; i++) {dp[i][0] = 0;dp[i][1] = i;}// 开始递推for (int i = 2; i <= N; i++) {for (int j = 2; j <= K; j++) {// 在区间 [1, i] 里确定一个最优值int left = 1;int right = i;while (left < right) {// 找 dp[k - 1][j - 1] <= dp[i - mid][j] 的最大值 kint mid = left + (right - left + 1) / 2;int breakCount = dp[mid - 1][j - 1];int notBreakCount = dp[i - mid][j];if (breakCount > notBreakCount) {// 排除法(减治思想)写对二分见第 35 题,先想什么时候不是解// 严格大于的时候一定不是解,此时 mid 一定不是解// 下一轮搜索区间是 [left, mid - 1]right = mid - 1;} else {// 这个区间一定是上一个区间的反面,即 [mid, right]// 注意这个时候取中间数要上取整,int mid = left + (right - left + 1) / 2;left = mid;}}// left 这个下标就是最优的 k 值,把它代入转移方程 Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1) 即可dp[i][j] = Math.max(dp[left - 1][j - 1], dp[i - left][j]) + 1;}}return dp[N][K];}
}作者:liweiwei1419
链接:https://leetcode-cn.com/problems/super-egg-drop/solution/dong-tai-gui-hua-zhi-jie-shi-guan-fang-ti-jie-fang/

【总结】

1.「动态规划」的两个思考方向:

1.自顶向下求解,称之为「记忆化递归」:初学的时候,建议先写「记忆化递归」的代码,然后把代码改成「自底向上」的「递推」求解;
2.自底向上求解,称之为「递推」或者就叫「动态规划」:在基础的「动态规划」问题里,绝大多数都可以从这个角度入手,做多了以后建议先从这个角度先思考,实在难以解决再考虑「记忆化递归」。

2. 「动态规划」五步走

第 1 步:定义状态
第 2 步:推导状态转移方程
第 3 步:考虑初始化
第 4 步:考虑输出
第 5 步:思考状态压缩

3.二分查找优化

参考链接:https://leetcode-cn.com/problems/super-egg-drop/solution/dong-tai-gui-hua-zhi-jie-shi-guan-fang-ti-jie-fang/.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习(152):字节缓冲输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

SDUTOJ3469_深度优先搜索练习之神奇的矩环(DFS)

深度优先搜索练习之神奇的矩环 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 小鑫的女朋友被魔王抢走了&#xff01; 魔王留给小鑫一张n*m大的表&#xff0c;上面有各种各样的颜色&#xff0c;用A-Z这26个字母来表示。魔王留给他一个任务…

PHP水果店管理系统,水果店连锁店管理系统实现一体化功能

现在的人们越来越注重养生&#xff0c;特别是饮食养生那么水果就成为了客户的首选之一&#xff0c;随着水果的市场需求越来越大&#xff0c;想开水果店的创业者越来越多&#xff0c;连锁水果店我们看到的店面也越来越多&#xff0c;由于季节或者是时间的问题会很容易导致水果变…

[剑指offer]面试题第[58]题[Leetcode][JAVA][第151题][翻转单词][字符串常用函数总结]

【问题描述】 给定一个字符串&#xff0c;逐个翻转字符串中的每个单词。示例 1&#xff1a; 输入: "the sky is blue" 输出: "blue is sky the"【解答思路】 1. 双指针 倒序遍历字符串确定边界添加单词拼接字符串 返回 时间复杂度&#xff1a;O(N) 空间…

java学习(153):字符输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

java学习(154):文件复制

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][面试题 16.03. 交点]

【问题描述】面试题 16.03. 交点 给定两条线段&#xff08;表示为起点start {X1, Y1}和终点end {X2, Y2}&#xff09;&#xff0c;如果它们有交点&#xff0c;请计算其交点&#xff0c;没有交点则返回空值。要求浮点型误差不超过10^-6。若有多个交点&#xff08;线段重叠&am…

[Leedcode][JAVA][第146题][LRU][哈希表][双向链表]

【问题描述】 LFU 运用你所掌握的数据结构&#xff0c;设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作&#xff1a; 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果密钥 (key) 存在于缓存中&#xff0c;则获取密钥的值&#xff08;总是正数&…

java学习(155):序列化

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第445题][链表][栈]

【问题描述】445. 两数相加 II 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。进阶&#xff1a;如果输入链表不能修改…

java学习(156):反序列化

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第355题][设计推特][面向对象][哈希表][链表][优先队列]

【问题描述】355 设计推特 设计一个简化版的推特(Twitter)&#xff0c;可以让用户实现发送推文&#xff0c;关注/取消关注其他用户&#xff0c;能够看见关注人&#xff08;包括自己&#xff09;的最近十条推文。你的设计需要支持以下的几个功能&#xff1a;postTweet(userId, …

java学习(157):线程的引入

//线程 public class test102 extends Thread{public void run(){while (true){System.out.println("我是线程1"this.getName());try {Thread.sleep( 1000 );}catch (InterruptedException e){e.printStackTrace();}}} }//线程 public class test103 extends Thread{…

【读书笔记】计算机是怎样跑起来的

2018年底读的&#xff0c;才整理完笔记。说说感想吧&#xff0c;每个章节虽然都是基础的知识&#xff0c;但是每次读起来还是收获颇多&#xff0c;很多自己说不清楚或者不理解的概念&#xff0c;感觉在认识层面有些结成网了。对于每个方面的专业知识&#xff0c;要按需深入学习…

[剑指offer][JAVA]面试题[第23题][合并K个排序链表][分治][优先队列]

【问题描述】23.合并K个排序链表 合并 k 个排序链表&#xff0c;返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: [1->4->5,1->3->4,2->6 ] 输出: 1->1->2->3->4->4->5->6【解答思路】 1. 两两合并 public class Soluti…

[Leedcode][JAVA][第542题][01矩阵][BFS]

【问题描述】542. 01 矩阵 给定一个由 0 和 1 组成的矩阵&#xff0c;找出每个元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例 : 输入: 0 0 0 0 1 0 1 1 1 输出: 0 0 0 0 1 0 1 2 1 注意: 给定矩阵的元素个数不超过 10000。 给定矩阵中至少有一个元素是 0。 矩阵…

java学习(159):两个线程共同完成1到100计算

//利用两个线程实现1到100的计算 public class MyRannable implements java.lang.Runnable{private Thread th_0;private Thread th_2;int sum0;//存储累加和的结果int i1;public void run(){String thNameThread.currentThread().getName();//获取当前线程的名字while (i<…

java学习(160):interrupt方法

import java.util.PrimitiveIterator;public class Classroon implements Runnable {private Thread student;//学生线程private Thread teacher;//老师线程public Classroon(){student new Thread( this,"小迷糊" );teacher new Thread( this,"大教授" …

elementui图片上传php,vue+element-ui+富文本————图片上传

最近用vueelement-ui开发一套后台管理系统&#xff0c;其中项目中需要用到富文本编辑器&#xff0c;这里总结下开发过程中遇到的坑和使用方法。刚开始用的是vue-quill-editor结合element-ui上传图片到服务器&#xff0c;name问题来了 按照官方文档上面的方式。下面是我的代码cl…

[剑指offer][JAVA][面试第40题][最小的k个数][快选][堆][BST]

【问题描述】面试第40题 最小的k个数 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2、3、4。 示例 &#xff1a; 输入&#xff1a;arr [3,2,1], k 2 输出&#xff1a;[1,2] …