🎉 前言
众所周知,递归是算法中很重要的一种思想,今天我希望以几个典例来讲讲我对递归的一些看法。废话不多说,让我们开始吧。
🎉 典例1 斐波那契数列
leetcode的第509题,是一道关于斐波那契数列的题目,题目如下:
斐波那契数列有这样的性质: f(n) = f(n-1) + f(n-2), 其中f(0) = 1,f(1) = 1。
现在给定一个正整数 n 要求计算出 f(n) 的大小
这道题目一般的解题思路是用循环的手段,不断的计算并累加,最终的到结果,参考代码如下:
class Solution {
public int fib(int n) {
if(n == 0){
return 0;
}
int dp[] = new int[n];
int res = 0;
if(n == 1 || n==2){
return 1;
}
dp[0] = 1;
dp[1] = 1;
for(int i=2;i<n;i++){
dp[i] = dp[i-1] + dp[i-2];
if(i == n-1){
return dp[i];
}
}
return 0;
}
}
这样看来代码一点也不简洁,但事实上如果你会一点递归的思想,用短短几行代码就能搞定。
先上代码:
class Solution {
public int fib(int n) {
if(n == 0){
return 0;
}
if(n == 1 || n == 2){
return 1;
}
return fib(n-1) + fib(n-2);
}
}
代码很简单,我们可以逐行来分析一下
首先,我们需要明确fib(n)代表的是什么意思,显然,在代码中fib(n)表示斐波那契数列的第n项,那么根据题意,我们可以将公式改写成
fib(n) = fib(n-1) + fib(n-2);
这样我们就得到了一个通项公式,任何一项斐波那契数列都可以用这个式子表示。
OK,再让我们回到源代码,我希望读者不要将fib(n)看成是一个函数,而是将其抽象成一个变量,
那么
if(n == 0){
return 0;
}
if(n == 1 || n == 2){
return 1;
}
return fib(n-1) + fib(n-2);
这几行代码就很好理解了,n=0表示第0项,根据题意返回0,n=1和n=2根据题意返回1,n>2,根据通项公式返回 第n-1和第n-2项之和,即fib(n-1) + fib(n-2),不知道讲到这里读者有没有get到我的点,如果没有请轻点喷😅。
这里还需要多说几句,其实前两个判断语句还起着终止递归的作用,因为本质上我们从实现细节的角度来看,最终递归是不可能一直进行下去的,fib(n-1)和fib(n-2)最终都会回到fib(1)+fib(2)上,所以这就是我为什么说判断语句起着终止递归的作用。
🎉 总结
从这道简单的例题中,我们可以总结出以下几点经验:
1.要明确递归函数的含义,必要时可将其抽象成一个变量
2.要有递归终止条件
3.要明确递归公式
最后附上几道练习,希望大家可以举一反三,触类旁通。
1.计算阶乘
//递归计算阶乘
class test01{
public static void main(String[] args) {
test01 t1 = new test01();
System.out.println(t1.fib(5));
}
//fib表示前i项的阶乘
public int fib(int n){
if(n == 0 || n == 1){
return 1;
}
return n*fib(n-1);
}
}
这里的递归函数同样简洁,终止递归的条件语句 + 递推公式 n * fib(n-1),而这里fib(n-1)含义表示第n-1项的阶乘。
2.计算100以内的正整数之和
//递归计算100以内的正整数和
class test02{
public static void main(String[] args) {
test02 t2 = new test02();
System.out.println(t2.fib(100));
}
//fib表示前i项的整数和
public int fib(int n){
if(n == 1){
return 1;
}
return n+fib(n-1);
}
}
3.计算10的n次方
//递归计算10的n次方
class test03{
public static void main(String[] args) {
test03 t3 = new test03();
System.out.println(t3.fib(4));
}
//fib表示前i项的整数和
public int fib(int n){
if(n == 0){
return 1;
}
return 10*fib(n-1);
}
}