06 递归
目录

递归是一种应用非常广泛的算法(或者编程技巧)。很多数据结构和算法的编码实现都要用到递归,比如 DFS 深度优先搜索、前中后序二叉树遍历等等。所以,搞懂递归非常重要。
1 特性
基本上,所有的递归问题都可以用递推公式来表示。要想使用递归解决问题,必需满足三个前提条件:
- 一个问题的解可以分解为几个子问题的解,子问题就是规模更小的问题
- 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
- 存在递归终止条件
1.1 如何写递归代码
写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递推公式,然后再找出终止条件,最后将递推公式和终止条件翻译成代码。
编写递归代码的关键是,只要遇到递归,我们就把它抽象成一个递推公式,不用想一层层的调用关系,不要试图用人脑去分解递归的每个步骤。
1.2 递归存在的问题
使用递归时会存在很多问题,最常见的两个是:
- 递归代码要警惕堆栈溢出
- 递归代码要警惕重复计算
在时间效率上,递归代码里多了很多函数调用,当这些函数调用的数量较大时,就会积聚成一个可观的时间成本。在空间复杂度上,因为递归调用一次就会在内存栈中保存一次现场数据,所以在分析递归代码空间复杂度时,需要额外考虑这部分的开销。
1.3 应用
递归有利有弊,利是递归代码的表达力很强,写起来非常简洁;而弊就是空间复杂度高、有堆栈溢出的风险、存在重复计算、过多的函数调用会耗时较多等问题。所以,在开发过程中,我们要根据实际情况来选择是否需要用递归的方式来实现。
参考: