如何编程获得最多的年终红包奖?文章转载自公众号 ,点击蓝色“五分钟学算法”关注我哟 加个“星标”,一起学算法 作者 | channingbreeze 来源公众号 | 互联网侦察 小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进BAT互联网公司。 今天小史又去了一家互联网小巨头公司面试了。 【面试现场】 小史眉头一皱,发现事情并不简单。 题目:在数字矩阵中,从左上角到右下角,每次只能向右或向下,如何规划路径,能获得最大数字总和? 小史开始仔细分析问题,一时间竟想不到很好的方法。 小史心中反复默念题目,进行思考。 小史仔细回忆起了吕老师教他的华容道搜索算法。 【请教大神】 回到学校,小史把面试情况和吕老师说了一下。 吕老师:红色和蓝色两条路都能到达中间的100这个点,但是很明显,红色的路拿到的奖金更多。所以蓝色的路,后面不管再怎么走,都不可能拿到最大的奖金数了。 吕老师:假设蓝色路径再往后走出一条绿色路径是最大奖金,那么我把蓝色路径替换成红色路径,红色加绿色得到的奖金就比蓝色加绿色得到的多呀。 【记忆化搜索】 小史:哦,我明白了,这样我每搜到一个点,都可以和这个数比较,如果比它大,就更新这个数,继续搜,如果比它小,就不搜了,直接剪枝。 理解了算法之后,小史的代码写起来也是非常快,不一会儿就写好了: DeepFirstSearch.java
(友情提示:可左右滑动) Main.java
(友情提示:可左右滑动) 运行结果
【记忆广搜】 吕老师:记忆深搜确实可以剪枝,但是假如有人刻意安排数字,把较小的数都安排在你先搜的路径上,那么你的计算量还是不会减少太多。 小史:还有这么坏的人呢?不过你这样一说我到想起来,深搜确实缺少一种“全局观”,可能第一条路搜完了,再来看第二条路,发现更好,结果第一条路全白搜了。 理解了算法之后,小史的代码写起来也是非常快,不一会儿就写好了: BreadthFirstSearch.java
(友情提示:可左右滑动) Main.java
(友情提示:可左右滑动) 运行结果
【动态规划】 吕老师:小史,代码写得不错,咱们再来看看广搜的过程,其实就是在搜索的过程中从左上到右下计算出了best(i,j),所以为啥我们不能直接算出best(i,j)呢? 理解了算法之后,小史的代码写起来也是非常快,不一会儿就写好了: DynamicProgramming.java
(友情提示:可左右滑动) Main.java
(友情提示:可左右滑动) 运行结果
【动态规划解析】 吕老师:状态的定义要满足几个点,第一,问题的答案是某种状态,或者可由状态进行推导。第二,当前状态可以由之前的状态推导而来。 【状态压缩】 小史:哦,我知道了,这道题,如果按照斜线方向来计算,只需要保留一条斜线的状态,就能计算出下一条斜线。所以之前的状态就不需要保留了。 理解了算法之后,小史的代码写起来也是非常快,不一会儿就写好了: DpCompressed.java
(友情提示:可左右滑动) Main.java
(友情提示:可左右滑动) 运行结果
PS:这次这篇花费了两周时间。如果你看到了这里,并且有所收获的话,可以动动手指转发一下哦,小史和吕老师都会感谢你。 END原 创 热 文 推 荐 |
朋友会在“发现-看一看”看到你“在看”的内容