介绍
如图就是斐波那契数列
当x=1,2时,fib=1; x>2时,fib=前两项之和
问题
现在要求输入一个正整数 n ,请你输出斐波那契数列的第 n 项。
用函数简单实现一下
int Fibonacci(int n) {
//需要先判断结束条件,1,2时返回1
if(n==1||n==2) return 1;
//返回前一项跟前两项的和
return Fibonacci(n-1)+Fibonacci(n-2);
}
但是输入的n非常大的时候时间复杂度也会变得非常高
因此可以用记录备忘录减少重复的计算,每次查表后打表,最后返回dp[n]
int dp[41]={0,1,1};
int Fibonacci(int n) {
if(n==1||n==2) return 1;
//查表,非0即存在,存在直接返回
if(dp[n]) return dp[n];
//不存在记录备忘录
//这里不能写dp[n]=dp[n-1]+dp[n-2];因为3往后的前面dp数组还没构建,全为0
dp[n]=Fibonacci(n-1)+Fibonacci(n-2);
return dp[n];
}
DP
不需再递归
int dp[41]={0};
int Fibonacci(int n) {
//初始化dp[1] dp[2]
dp[1]=1,dp[2]=1;
//给后面每项赋值
for(int i=3;i<=n;i++) dp[i]=dp[i-1]+dp[i-2];
return dp[n];
}
因为实际上求dp[n]的时候只需再知道dp[n-1] dp[n-2],只需一共3个变量,就能算出答案,还可以继续对On空间优化成O1
int Fibonacci(int n) {
int a=1,b=1,c=1;
for(int i=3;i<=n;i++){
//算完c 把a,b往后移
c=a+b;a=b;b=c;
}
//小于3时都等于1
return c;
}
对比
普通递归
备忘录
dp
dp优化