递归 (Recursion)
递归(Recursion)概述
概念
- 递归是一种算法,也是一种编程技巧,应用非常广泛。
- 递归求解问题的分解过程:去的过程叫“递”,回来的过程叫“归”
- 应用:DFS深度优先搜索、前中后序二叉树遍历
优缺点:
- 优点:
- 递归代码表达能力强,写起来简洁
- 缺点:
- 空间复杂度高
- 有堆栈溢出的风险
- 存在重复计算
- 过多的函数调用会耗时较多
递归公式Demo
f(n)=f(n-1)+1 其中,f(1)=1
f(1) = 1;
f(2) = 2;
f(n) = f(n-1)+f(n-2)
什么场景的问题适合用递归解决
需要满足以下三个条件
- 一个问题的解可以分解为几个子问题的解
- 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
- 存在递归终止条件
- 不能出现无限循环
如何编写递归代码
- 核心思想:写出递推公式,找到终止条件,然后将递推公式转化为代码
- 方法:
- 找到如何将大问题分解为小问题的规律,并且写出递推公式
- 推敲终止条件
- 将递归公式和终止条件翻译成代码
- 注意:
- 只要遇到递归,就把它抽象成一个递推公式,不用想一层层的调用关系,不要视图用人脑去分解递归的每个步骤(重复的步骤交给计算机完成)
递归常见问题
- 递归代码要警惕堆栈溢出
- 可以声明一个全局变量来控制递归深度,可以一定程度避免堆栈溢出
- 递归代码要警惕重复计算
- 通过某种数据结构来保存已经求解过的值,从而避免重复计算
- 过多的函数调用会耗时较多,空间复杂度高
递归代码改非递归代码
- 递归代码都可以改为迭代循环的非递归写法
- 本质上是:将自动递归改为手动递归,本质问题没有解决
- 实现:
- 抽象递推公式
- 初始值和边界条件
- 用迭代循环实现