java编程有一筐鸡蛋,妙解谷歌压箱底面试题:如何正确的从楼上抛鸡蛋

本文主要是介绍java编程有一筐鸡蛋,妙解谷歌压箱底面试题:如何正确的从楼上抛鸡蛋,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

google-interview-question-2.html

作者:Marcin Moskala

编译:ShanLIU、笪洁琼、Harry

关于编程工作有很多很不错的面试谜题。新年之际,我把压箱底儿的一道好题,同时也是传说中谷歌招聘官最喜欢问的一道题找出来了!

今天我们来好好八一八这道题,如果你今年恰好想去谷歌面试,可以抓紧多读几遍!(绝对不会出现下图的情况,我们只放有口碑的神助攻

google-interview-question-2.html

题目如下:

你在一座100层的高楼大厦里工作,拿到了两个一模一样的鸡蛋。你得搞明白鸡蛋最高可以从几层楼扔出去还不摔坏。

请提出一个算法,能找到投掷鸡蛋却保证不摔坏的最少次数~

我们可以先做些假设:

如果鸡蛋从某一楼层跌落而不摔坏,那么当它从更低楼层跌落也不会有破损。

一个在被投掷之后完好无损的蛋可以被再利用。

一颗鸡蛋如果破损,则必会被丢弃。

跌落对于所有鸡蛋都具有同等效应。

如果一颗鸡蛋从某一楼层跌落之后受损,那么当它从更高楼层跌落后必定会摔坏。

如果一颗鸡蛋从一次跌落中存活下来,那么它一定会从更短程的降落中存活。

大多数人会写出算法来解决这个谜题(我们同样也是会用算法),然而实际上有更容易的办法。

敲黑板说重点啦!

google-interview-question-2.html

最简单的回答

最简单的方式来获取最少楼层数就是将鸡蛋从第一层扔出,然后第二层,然后依次往后叠加。这样一来,当鸡蛋破碎那一刻我们就知道是这一层了。这是一个可靠的算法,但是在最差的情况下它需要的投掷次数是100次。

需要注意的最重要的一点是,假如你只有一颗鸡蛋,这是唯一可靠的方法。所以在你打破第一颗鸡蛋时就需要开始运用这个算法。

直觉性的答案

这样,我们应该把这100层划分成更小数目的的区间,以尽可能有效地应用这第一颗鸡蛋。因此,一个凭直觉的而且颇受欢迎的方法是从1/第n层逐层检查。

比方说,从第一层到第三层。由此得出算法如下:

从33楼投掷出这颗鸡蛋。如果它破损了,那么我们用第二颗鸡蛋检查第32层楼。

否则,我们从33+ (67 *1/3) =55层楼扔,如果鸡蛋破损,我们再来用第二颗鸡蛋检查34层到55层。

对于1/3最坏的情况是最大值是33层,这样一来,我们可能可以找到一个完美的n,借助一些动态编程手段,来优化投掷次数。这是一个体现编程思维的有价值的解决方式,然而这不是最优解。

完美解决方案

为了理解完美解法,我们需要理解均衡状态,用于计算出在最坏情境下所需的投掷次数。

google-interview-question-2.html

这里,F(n) 是我们从开始投掷鸡蛋计算的下一层楼层。

假如我们引入以下的变量:

google-interview-question-2.html

那么均衡点将会是如下:

google-interview-question-2.html

2c501cacfd5945fcc881fa6709a4d31b.png最优解是当这个方程里的所有参数都相等。我们是如何取得的呢?从末尾开始看,最后的D(n)将会变成1,因为我们最终将会到达一个点,就是只有单一的一层楼用于投掷第一颗鸡蛋。所以D(n-1)应该等于2,因为它相比于第一颗鸡蛋少了一次投掷。

我们接着会发现第一颗鸡蛋最终应该是从第99层楼投掷,之前是从99-2=97层,再往前则是97-3=94层,90, 85, 79, 72, 64, 55, 45, 34, 22,然后是第九层。这是一个最优解!这样一来,我们需要在最坏的情况下投掷14次(最小的差别在于13,但是我们还需要在第九层额外投一次)。

检查

好啦,我们已经有了解决方案,可以无需任何其他帮助来解开它。现在是时候验证它是否正确了!为此,我们可以写一个Kotlin方程式。

首先,我们来解释一下对一些决策来说,是如何计算投掷次数的。当我们有2层或者更少的层数,那么我们需要按照剩余的楼层数来投掷尽量多的次数。否则我们应该调用如下方呈现的均衡函数:

google-interview-question-2.html

这里我们调用了bestMaxThrows 函数,这是一个假设函数,它会返回一个投掷次数的数值,假定接下来的一系列决策是完美的。

我们是这样定义它的:

google-interview-question-2.html

再一次的,我们刚刚授权给了bestNextStep 函数来计算“下一层的最优解”。这个函数很好的为我们指明了下一步的方向,我们可以简单地定义它:当只有二层或更少的楼层待检验,那我们会从第一层扔出鸡蛋,否则我们需要检查所有备选项以找到最优解。

下面是具体执行步骤:

google-interview-question-2.html

再一次的,我们刚刚授权给了bestNextStep 函数来计算“下一层的最优解”。这个函数很好的为我们指明了下一步的方向,我们可以简单地定义它:当只有二层或更少的楼层待检验,那我们会从第一层扔出鸡蛋,否则我们需要检查所有备选项以找到最优解。

下面是具体执行步骤:

google-interview-question-2.html

注意,这个函数使用了maxThrows 函数,所以涉及到了循环。这不是个问题,因为当bestNextStep 调用到maxThrows时,它总是调用一个小于floorsLeft 的数(因为nextFloor 总是大于0)。我们调用这个函数之前先加一些缓冲,用于加速这些运算。

google-interview-question-2.html

首先,我们看看它是否返回和之前计算相同的结果。

google-interview-question-2.html

结果看着不错,我们再看看下面几步:

google-interview-question-2.html

结果:

9, 22, 34, 45, 55, 64, 72, 79, 85, 90, 94, 97, 99, 100,

正是我们计算的结果!赞!

google-interview-question-2.html

拓展

现在我们有了一套可以解决很多相似问题的不错的算法。比如说,我们可以稍微修改一下来计算最随机的情况下的投掷次数。我们也可以看看这一最小数值如何根据建筑高度不同而有所区别。

下图回答了以上的问题:

google-interview-question-2.html

(该图展示了最坏情景的最少投掷次数,纵轴是楼层数,横轴是投掷次数,曲线代表最优投掷次数。)

结论

你现在对于谷歌的面试准备更充分了,但更重要的是,你相比以前更具备算法思想。这个算法呈现了一个很好的,高效型的方法。还可应用于解决我们每日工作中的许多问题。

这篇关于java编程有一筐鸡蛋,妙解谷歌压箱底面试题:如何正确的从楼上抛鸡蛋的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/325623

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll