1111
1212> 纯粹的函数式编程中没有循环,只有递归。
1313
14- 接下来我们来讲解以下递归 。通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解
14+ 接下来我们来讲解一下递归 。通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解
1515
1616### 递归的三个要素
1717
2929
3030- 汉诺塔问题
3131
32+ - 杨辉三角
33+
34+ ### 练习递归
35+
36+ 一个简单练习递归的方式是将你写的迭代全部改成递归形式。比如你写了一个程序,功能是“将一个字符串逆序输出”,那么使用迭代将其写出来会非常容易,那么你是否可以使用递归写出来呢?通过这样的练习,可以让你逐步适应使用递归来写程序。
37+
38+ ### 递归中的重复计算
39+
40+ 递归中存在这么多的重复计算,一种简单的方式就是记忆化递归。即一边递归一边使用“记录表”记录我们已经计算过的情况,这样就避免了重复计算。而动态规划中 DP 数组其实和“记录表”一样。
41+
42+ 你可以尝试使记忆化更加通用和非侵入性,即应用记忆化技术而不改变原来的功能。 (提示:可以参考一种被称作 decorator 的设计模式)。
43+
44+ ### 递归的时间复杂度分析
45+
46+ 敬请期待我的新书。
47+
3248## 动态规划
3349
34- ` 如果说递归是从问题的结果倒推,直到问题的规模缩小到寻常。 那么动态规划就是从寻常入手, 逐步扩大规模到最优子结构。 ` 这句话需要一定的时间来消化,
50+ ` 如果说递归是从问题的结果倒推,直到问题的规模缩小到寻常。 那么动态规划就是从寻常入手, 逐步扩大规模到最优子结构。 ` 这句话需要一定的时间来消化,
3551如果不理解,可以过一段时间再来看。
3652
3753递归的解决问题非常符合人的直觉,代码写起来比较简单。但是我们通过分析(可以尝试画一个递归树),可以看出递归在缩小问题规模的同时可能会
3854重复计算。 [ 279.perfect-squares] ( ../problems/279.perfect-squares.md ) 中 我通过递归的方式来解决这个问题,同时内部维护了一个缓存
3955来存储计算过的运算,那么我们可以减少很多运算。 这其实和动态规划有着异曲同工的地方。
4056
41- 我们结合求和问题来讲解一下, 题目是给定一个数组,求出数组中所有项的和,要求使用递归实现。
57+ 我们结合求和问题来讲解一下, 题目是给定一个数组,求出数组中所有项的和,要求使用递归实现。
4258
4359代码:
4460
@@ -142,15 +158,17 @@ f(n) = f(n-1) + f(n-2) 就是【状态转移公式】
142158
143159这一点是和递归一样的, 但是动态规划是一种类似查表的方法来缩短时间复杂度和空间复杂度。
144160
145- 画表格的目的就是去不断推导,完成状态转移, 表格中的每一个cell都是一个 ` 小问题 ` , 我们填表的过程其实就是在解决问题的过程,
161+ 画表格的目的就是去不断推导,完成状态转移, 表格中的每一个 cell 都是一个 ` 小问题 ` , 我们填表的过程其实就是在解决问题的过程,
146162我们先解决规模为寻常的情况,然后根据这个结果逐步推导,通常情况下,表格的右下角是问题的最大的规模,也就是我们想要求解的规模。
147163
148164比如我们用动态规划解决背包问题, 其实就是在不断根据之前的小问题` A[i - 1][j] A[i -1][w - wj] ` 来询问:
149165
1501661 . 我是应该选择它
1511672 . 还是不选择它
152168
153- 至于判断的标准很简单,就是价值最大,因此我们要做的就是对于选择和不选择两种情况分别求价值,然后取最大,最后更新cell即可。
169+ 至于判断的标准很简单,就是价值最大,因此我们要做的就是对于选择和不选择两种情况分别求价值,然后取最大,最后更新 cell 即可。
170+
171+ 其实大部分的动态规划问题套路都是“选择”或者“不选择”,也就是说是一种“选择题”。 并且大多数动态规划题目还伴随着空间的优化,这是动态规划相对于传统的记忆化递归优势的地方。除了这点优势,就是上文提到的使用动态规划可以减少递归产生的函数调用栈,因此性能上更好。
154172
155173### 相关问题
156174
@@ -169,3 +187,5 @@ f(n) = f(n-1) + f(n-2) 就是【状态转移公式】
169187本篇文章总结了算法中比较常用的两个方法 - 递归和动态规划。
170188
171189如果你只能借助一句话,那么请记住:` 递归是从问题的结果倒推,直到问题的规模缩小到寻常。 动态规划是从寻常入手, 逐步扩大规模到最优子结构。 `
190+
191+ 另外,大家可以去 LeetCode 探索中的 [ 递归 I] ( https://leetcode-cn.com/explore/orignial/card/recursion-i/ ) 中进行互动式学习。
0 commit comments