习题讲解 | Google, Facebook高频面试题动态规划(DP)
Posted 来Offer网
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题讲解 | Google, Facebook高频面试题动态规划(DP)相关的知识,希望对你有一定的参考价值。
Coin Change II,不仅是Google、Facebook、Microsoft、Yahoo等公司的高频面试题,也是一道非常经典的动态规划(DP)的题目。
本期习题讲解,我们就通过这道题目,帮助大家对动态规划有一个更进一步的理解。
先一起来看看题目:
题目描述
You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.
Note: You can assume that
0 <= amount <= 5000
1 <= coin <= 5000
the number of coins is less than 500
the answer is guaranteed to fit into signed 32-bit integer
Example 1
Input: amount = 5, coins = [1, 2, 5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
Example 2
Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3
Input: amount = 10, coins = [10]
Output: 1
考点解析
这道题目其实有很多种解法。比如有的同学会考虑用DFS(深度优先搜索)。这个方法其实是可行的,但问题是search space会指数型的增长。
因此,这道题目一个更好的方法就是动态规划(DP)。
DP的核心思想就是要想方设法把一个大问题切割成一个或多个小问题,然后用小问题的解去构建大问题的解。
动态规划一向是大公司onsite考察的重点,也是同学们知识上的一个难点。
动态规划问题的难点主要在于:
如何在短暂、紧张的面试过程中,快速的通过观察和divide & conquer的方法定义subproblem状态和状态转移方程,并写出bug free的代码。
接下来,我们有请吴老师为我们详解这道题的答案:
主讲人:吴老师
FLGU一线公司资深工程师
全国信息学奥林匹克竞赛(NOI)金牌
NOI中国国家队教练。
或扫描下方二维码
进入来Offer官网观看
解题思路
在本题中,吴老师讲解了从naive的动态规划算法,到最终一个时间、空间上都非常effient的算法是如何一步一步优化而来的。
解法1:Naive Dynamic Programming
这个题目是一个二维的动态规划问题,一方面是硬币的种类(n),另一方面是我们要拼凑成的数额(m)。
因此,这个问题可以刻画成:
f[i][j] = the number of combination to make up amount j with the first i types of coins.
这个题目的Base Case相对比较容易想到:
f[0][0] = 1
f[0][1...m] = 0
即用0种硬币,拼凑数额0,共有1种方法。而用0种硬币,拼凑大于0的任意数额,都不可能。
这个题目的Induction rule是:
在这个基础上,我们就能比较容易的写出这个题目的代码。
解法2:Faster Dynamic Programming
上一个解法虽然可以解决这个问题,但时间复杂度比较高。
进一步观察induction rule我们可以发现,其中有非常多冗余的计算。
如下图红色部分所示:
因此,我们可以进一步的优化induction rule:
解法3:Faster & More Space-efficient DP
在上一个解法的基础上,我们还可以进一步的观察:
以这个图为例,我们发现:
当我们求蓝色的f[1][6]的值的时候,根据induction rule,它只跟红色的两个状态f[0][6]和f[1][6 - coins[0]]相关。
这两个状态需要在算蓝色的f[1][6]之前算出来。
而它们刚好分别位于f[1][6]同一列上一行,和同一行前面某列。
这就意味着我们要把整个状态表格填完应该遵循从上往下、从左往右、逐行填写的顺序。
通过观察还可以得出,按照这个顺序我们可以用一个一维数组维护红色范围内的值,优化算法的空间复杂度。
当我们填写蓝色格子的时候,它的左侧都是已经填好的同行的结果,右侧仍然是上一行对应的结果。如下图所示:
代码实现
算法与代码中需要注意的细节处理及时间、空间复杂度分析请观看视频讲解。
E/N/D
来Offer官网最新上线视频
大规模搜索系统
大规模搜索系统为何如此重要?
其构建和实现的难点有哪些?
Wish、Pinterest搜索团队Tech Lead
分享大规模搜索系统的实战故事。
习题322.
Coin Change
Google, Amazon, Yahoo, Microsoft 高频面试题
考点:动态规划
难度:中等
习题496.
Next Greater Elements I
Google 高频面试题
考点:数组、单调栈
难度:简单
视频观看方式
订阅我们,不错过每期视频更新。
1. 网站订阅
目前所有最新的公开课视频,均可在来Offer官网www.laioffer.com的“免费资源”菜单下观看和订阅。
订阅后,每期更新视频会及时发送到您的邮箱。
2. YouTube订阅
订阅来Offer官方YouTube频道,不错过每期更新。
关于我们
硅谷IT黄埔军校 —— 来Offer,是硅谷最具实力的高科技在线教育平台。
来Offer由清华CS校友和来自硅谷一线公司的资深高级工程师精英共同创立,秉承清华大学计算机人的传统,以严谨、认真的治学和科研精神,为学员提供IT培训、面试指导与职业发展咨询等一站式服务。
5年来,我们已成功帮助超过2000名学员拿到他们的dream offer!
查看完整offer榜单 (1-116周),欢迎登陆来Offer官方网站: www.laioffer.com
求职,你只需要一门课程!
以上是关于习题讲解 | Google, Facebook高频面试题动态规划(DP)的主要内容,如果未能解决你的问题,请参考以下文章
堆的相关习题 面试题17.14最小的K个数 347前K个高频元素 373查找和最小的K对数字