1、递归特征
1、执行时范围不断缩小,这样才能触底反弹。
举例:
- 阶乘:f(n) = n * f(n-1)
- 斐波那契:f(n) = f(n-1) + f(n-2)
- int leftDepth = getDepth(node.left); // 左 int rightDepth = getDepth(node.right)//右
以上:1.和2.的n在不断缩小;3.的范围缩小到左子树和右子树
2、终止判断在调用递归的前面。
在执行递归之前,一定会有一个终止条件。不然一直递归下去,直到栈溢出,抛出异常。
一个方法的递归调用可以多次,加一些逻辑处理。
public void recursion(参数0) {
if (终止条件) {
return;
}
//可能有一些逻辑运算1
recursion(参数1);
// 可能有一些逻辑运算2
recursion(参数2);
// ......3
recursion(参数n);
// 可能有一些逻辑运算
}
2、递归过程
- 找递归公式
- 从小到大找规律,可以先选几个较小的值验一下,再选几个较大的值验一下。
- 斐波那契数列:1、1、2、3、5、8、13、21….,即第一项 f(1) = 1,第二项 f(2) = 1…..,从第三项开始就满足:f(n) = f(n-1) + f(n-2)这就是我们要找的递归公式。
- 分情况确定终止条件
- 阶乘:当 n = 1 时,f(1) = 1。
- 有时候终止条件不止一个,斐波那契数列的递归公式f(n) = f(n-1) + f(n-2)里,如果n=2时会出现f(2)=f(1)+f(0),因为没有f(0),是从f(1)开始的,所以要将n==2也给限制住,所以结束条件:当 n <= 2 时,return 1;
- 有些情况不一定触底才反弹,而是达到某种要求就停止,这样需要考虑的情况会比较多。可以枚举,将可能的情况列举一下然后优化。
- 组合出完整条件
-
递归公式+终止条件
- 举例:斐波那契
-
int fibonacci(int n){
// 1.先写终止条件
if(n <= 2){
return 1;
}
// 2.再写递归公式
return fibonacci(n-1) + fibonacci(n - 2);
}
3、递归实例
例:第2关链表反转的递归法