递归是一个神奇的算法套路,得不到其精髓的人在墙外苦苦徘徊,网上关于此类算法思想的文章有很多,诚心需要学习的小伙伴建议耐心看完,这里分享一下大佬链接:
https://www.zhihu.com/question/31412436
前辈总结了递归的三大要素:
第一要素:明确你这个函数想要干什么
第二要素:寻找递归结束条件
第三要素:找出函数的等价关系式
文字功夫不是我们程序员的首选修炼,建议先从一些简单容易理解的题目入手,许多小白的第一简单递归实例通常为两个:
阶乘和斐波那契数列
阶乘的概念非常简单,这里就不再赘述。直接看代码
public static int Jiecheng(int n) {
if(n == 0 ){
return 1;//很多人在写阶乘的时候默认了n是大于0的情况,这会导致输入0的时候,0的阶乘为0,于事实逻辑相违背:规定上0的阶乘等于1
}
if(n <= 2) {
return n;
}
return n*Jiecheng(n-1);
}
回过头温习三要素,每当你使用递归这个方法,你先要弄清楚内在关系的函数表达式是什么,这一点对初学者相当困难,只能辅以题目的练习(即先习惯这种思维方式的表达),哪怕是阶乘本身相当简单的题目,你也首先需要拎清1和2的阶乘是它本身,从3开始调用这个函数,
f(3)=3^f(2) ->
f(2)= 2^f(1) ->
<- f(1) = 1
所以函数构造和所谓的递归结束条件你再细细品味:
我本来要求 f(3),但是不知道f(2),于是去函数中找这个f(2),函数告诉我,f(2)不用求了,就是你传过来的这个参数,好的,函数到这结束,然后从已知向上推导,f(2) = 2,f(3) = 3^f(2) = 3*2=6,所以递归也叫做递推。我们再来看下一个简单的题
斐波那契数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
在数学上,斐波那契数列以如下被以递推的方法定义:
F(0)=0,F(1)=1,
F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N)*
如果各位有基础,那用java基本实现不难:经典算法(老毛病,实现需要的时间复杂度过于恐怖,看思想,以后学到更好的再优化)
public int Fibonacci(int n) {
if(n == 0) {
return 0;
}
if(n == 1) {
return 1;
}
return Fibonacci(n-1) + Fibonacci(n-2);
}
今天我们不去考虑算法实现的时间复杂度的问题,先从思想上认知递归这种思想。