斐波那契数列各种方法求解
斐波那契数列(Fibonacci sequence)是指这样一组数字:1、1、2、3、5、 8、 13······,可以由递推公式F(n) = F(n-1)+F(n-2)得出,其初始值为:F(1) = 1, F(2) = (1) 。
在刷题的过程中,遇到了许多关于斐波那契数列变形的题目,所以在这里总结一下关于该数列的各种求解方法。
方法一:递归求解
主要是利用的斐波那契数列的递推公式实现。
int fibonacci(int n)
{
if(n <= 1)
return n;
return fibonacci(n-1)+fibonacci(n-2);
}
复杂度分析
时间复杂度:O(2^n)。
空间复杂度:O(n)。
方法二:正向求解
上述递归方法中,采用的是从n开始递归向前求解,这里可以选用正向求解的方法,一次计算F(1),F(2),F(3),F(4),······直到F(n)。
int fibonacci(int n)
{
if(n <= 1)
return n;
int f1 = 0;
int f2 = 1;
int res;
for(int i = 1; i < n; i++)
{
res = f1 + f2;
f1 = f2;
f2 = res;
}
return res;
}
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)。
方法三:公式求解
斐波那契的通项公式为:
F
(
n
)
=
1
5
[
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
]
.
F(n) = \frac {1} {\sqrt{ 5}}[( \frac {1+\sqrt{ 5}}{2})^{n}-( \frac {1-\sqrt{ 5}}{2})^{n}].
F(n)=51[(21+5)n−(21−5)n].
int fibonacci(int n)
{
if(n <= 1)
return n;
double sqrt_5 = sqrt(5);
return (1 / sqrt_5) * (pow((1 + sqrt_5)/2,n+1) - pow((1 - sqrt_5)/2, n + 1));
}
复杂度分析
时间复杂度:O(log(n)),因为上述公式中用到了pow 函数,故需要 log(n) 的时间。
空间复杂度:O(1)。
方法四:动态规划法
该问题也可以利用动态规划的方法进行求解。
斐波那契的第i个数据为第i-1个数与第i-2个数之和,令dp[i]表示第i个数据的值,则有:
d
p
[
i
]
=
d
p
[
i
−
1
]
+
d
p
[
i
−
2
]
.
dp[i] = dp[i-1] +dp[i-2].
dp[i]=dp[i−1]+dp[i−2].
初始值为:dp[[1]] = 1, dp[[2]]= 1;
int fibonacci(int n)
{
vector<int> dp(n+1);
dp[1] = 1;
dp[2] = 1;
for(int i = 3; i <= n; i++)
{
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
这个方法与正向求解方法其实本质上是一致的。但在空间复杂度上是不一样的。
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(n),动态数组dp需要n的空间。
-----------------------------------------------------------------------------------------
还有一些方法之后补充