编程学习笔记(LeetCode-509.斐波那契数)
<509> 斐波那契数列
- 问题重述:
已知:
\[F(n)=
\begin{cases}
0,\qquad \qquad \qquad \qquad \qquad \;\; n=0;\\
1,\qquad \qquad \qquad \qquad \qquad \;\; n=1;\\
F(n-1)+F(n-2),\qquad n>1,n \in{}N^*;\\
\end{cases}
\]
求:\(F(n)\)
其中:\(0\leqslant n \leqslant 30\)
方法一:动态规划+滚动数组
斐波那契数的边界条件是 F(0)=0 和 F(1)=1。当 n>1 时,每一项的和都等于前两项的和,因此有如下递推关系:
F(n)=F(n-1)+F(n-2)
由于 F(n) 只与 F(n-1) 和 F(n-2) 有关,那么就可以采用滚动数组的思想实现:

C++代码实现:
class Solution {
public:
int fib(int n) {
if(n<2){return n;}
//cur表示当前计算结果,n1和n2表示 n-1, n-2
int cur, n1, n2;
cur = 1;
n1 = 1;
n2 = 0;
for(int i = 3; i <= n; i++){
int temp = n1;
n2 = n1;
n1 = cur;
cur = n1 + n2;
}
return cur;
}
};
方法二:使用通项公式
斐波那契数列 \(F(n)\) 是齐次性递推,根据递推方程:
\[F(n) = F(n-1) + F(n-2)
\]
可以写出这样的特征方程:
\[x^2=x+1
\]
求得 \(x_1= \frac{1+\sqrt{5}}{2}\) ,\(x_2= \frac{1-\sqrt{5}}{2}\) 。设通解为 \(F(n)=c_1x_1^n+c_2x_2^n\) ,代入初始条件\(F(0)=0\) , \(F(1)=1\) ,得 \(c_1=\frac{1}{\sqrt{5}}\) , \(c_2=-\frac{1}{\sqrt{5}}\) 。因此斐波那契数列的通项公式如下:
\[F(n)=\frac{1}{\sqrt{5}}\left[\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n\right]
\]
得到通项公式公式后,就可以通过公式直接求解第 \(n\) 项。
- C++代码实现如下:
class Solution {
public:
int fib(int n) {
double sqrt5 = sqrt(5);
double fibN = pow((1 + sqrt5) / 2, n) - pow((1 - sqrt5) / 2, n);
return round(fibN / sqrt5);
}
};
- 注: 代码中使用的 pow 函数的时空复杂度与CPU支持的指令集相关。
备注: 摘录自LeetCode官方题目解析。
浙公网安备 33010602011771号