什么是递归?
递归介绍的文章已经非常多了,但是我发现它们都有一个共同的特点,都介绍得比较隐晦。很难抓住其本质,抓住重点;故写下此文给自己刷过的算法做一个小总结;
所有的算法不过是 for / while / do while / if else / 递归 这些基础算法,再加上编程思维(头脑风暴)组成;其中最难的就是递归,我在leetCode专题上刷递归的时候,曾经也是一脸的茫然,发现它好难啊,真的好难;但如果你一旦掌握了它的本质和核心,它并非如此的难。在看本文的时候,希望小伙伴们对栈(LIFO)和树的数据结构有最基本的认识,如果不认识请自行查阅资料;
相信很多小伙伴跟我当初一样,你说的我都知道,但是总是一看就会,一写就费。扎心了,铁汁。这个是没有办法的,需要多下功夫刻意练习。我强烈推荐把leetCode 树专题先刷起,因为树这个数据结构,它的本质上就是一个递归,用递归解决树的问题,是最合适的。
递归本质上就是把大问题划分成N个小问题解决,然后通过N个小问题进行组合/计算得到最终我们想求的大问题。在进行递归的刻意练习时候,我们先来记住一个万能模板;
```js
function recursion(...args){
//1.base case 终止条件,也常叫出口;
//2.process 本次递归你要解决的子问题,可能需要计算,组合什么的;
//3.call self level 自己调用自己,进入下一层递归;
//4.rest state 在第三步的时候可能需要改变一些递归公用的状态,将它们恢复;
}
```tips:初学递归写递归的时候我们都会经常犯错,就是人肉递归,一开始如果真的不是很熟悉可以这样,但是后面写熟悉了强烈建议不要人肉递归。人肉递归会让你非常的混乱,再说人脑能进行几层递归呢?QAQ
递归的本质
上面我说到了,递归的本质之一就是一棵树,用我们最熟悉不过的斐波那契数列来举例;
我相信很多小伙伴闭着眼睛都能知道斐波那契数列怎么求,不就是 f(n) = f(n - 1) + f(n - 2)
如果用递归写,就直接是照抄公式,写好终止条件就行了,没错,确实是这样;但是为什么递归能如此的简洁就把问题解决了呢?递归的本质又是什么呢?我相信是有很大部分同学是没有完全搞清楚的,没有搞清楚这一点,在写比较难的递归时候,就会陷入不会写的局面;

利用网上的一张图,我们人肉递归分析一下递归的状态树,要计算第四项斐波那契数列的值,就要知道第三项和第二项,以此递归;递归到我们可以明确的知道最前面的那两项。就可以得到最终的解了。
在这里,我们写递归之前我们要明确两个点,也是写递归必须要分析清楚的两个点。
- 解决的问题能够分解成N个子问题;能够利用子问题的解来组合计算得到最终的解。
- 递归非常的适合人脑的思考方式,只要把上面模板的四个问题想清楚,写递归真的不难。
我们来解一下这个递归
```js
function recursion(n){
//1.base case 终止条件是什么?因为 f(n) = f(n - 1) + f(n - 2);
// 所以终止条件必须是两项,第0项是0,第一项是1
if(n == 0) return 0;
if(n == 1) return 1;
//2.process 本次递归你要解决的子问题,我们要计算第N项的值,那么就要知道N-1和N-2项;
//3.call self 进入下一层递归;千万不要脑子人肉进递归里面去想,recursion(n - 1) 肯定能得到值
let cur = recursion(n - 1)
let pre = recursion(n - 2)
//4.rest state 在第三步的时候可能需要改变一些递归公用的状态,将它们恢复;
//在这里不需要重置任何公用的值
//最后我们返回最终的解,就是前两项的值之和,cur + pre,你不要去人肉递归想,进入函数去计算!
return pre + cur
}```接下来我以leetcode真题带大家感受一下这个模板,这里偷个懒直接vs code + 插件AC一些经典的递归题了。
1.二叉树最大深度(easy)
直接套模板,然后想清楚递归的四个问题;这里我直接给出 原题 链接,根据题目思考问题。

2.平衡二叉树(easy)

3.路径总和 II(Medium)

让你们感受一下模板的魅力QAQ

总结
递归的技巧远远不止这些,还有一些优化的技巧就不展开说了。递归关键的是多练,根据模板把四个问题想清楚就行了,一开始你可以人肉递归,后面熟悉了千万不要再人肉递归了。
可能有的小伙伴说递归的性能不好呀,什么的;不存在的,如果你写的是傻递归,性能确实存在很大的问题,如果你利用一些手段优化,想清楚递归状态树,提前剪枝,或者尾递归优化,性能也是一样的;重点是,递归真的很适合人脑的思考方式进行编程,很简洁。但是注意千万不要人肉递归;容易混乱。