斐波那契数列问题
给定整数N,返回斐波那契数列的第N项。类似地,
给定整数N,代表台阶数,一次可以跨2个或者1个台阶,返回有多少种走法
假设农场中成熟的母牛每年只会生1头小母牛,并且永远不会死。第一年农场有1只成熟的母牛,从第二年开始,母牛开始生小母牛。每只小母牛3年之后成熟又可以生小母牛。给定整数N,求出N年后牛的数量。
上述问题可以优化为O ( l o g N ) O(logN) O ( l o g N ) 的实现。
LeetCode 509 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n)
该问题可以通过以下种方式来实现:
递归实现,时间复杂度为O ( 2 N ) O(2^N) O ( 2 N )
int fib (int n) {
if (n <= 1 ) return n;
if (n == 2 ) return 1 ;
return fib (n-1 )+fib (n-2 );
}
我们在计算F ( N ) F(N) F ( N ) 的时候前面已经计算过F ( n − 1 ) F(n-1) F ( n − 1 ) 可以通过记忆F ( n − 1 ) F(n-1) F ( n − 1 ) 来降低计算的复杂度。
动态规划。时间复杂度为O ( N ) O(N) O ( N ) ,空间复杂度为O ( N ) O(N) O ( N )
int fib (int n) {
vector<int > dp = vector <int >(n+2 );
dp[0 ] = 0 , dp[1 ] = 1 ;
for (int i = 2 ; i <= n; i++) {
dp[i] = dp[i-1 ] + dp[i-2 ];
}
return dp[n];
}
f [ n ] f[n] f [ n ] 只依赖f [ n − 1 ] f[n-1] f [ n − 1 ] 和f [ n − 2 ] f[n-2] f [ n − 2 ] 可以进行空间压缩,来降低空间复杂度。
动态规划+滚动数组,时间复杂度为O ( N ) O(N) O ( N ) ,空间复杂度为O ( 1 ) O(1) O ( 1 )
int fib (int n) {
if (n <= 1 ) return n;
int pre = 1 , prepre = 0 ;
int cur = 1 ;
for (int i = 2 ; i <= n; i++) {
cur = pre + prepre;
prepre = pre;
pre = cur;
}
return cur;
}
矩阵快速幂,时间复杂度为O ( l o g 2 N ) O(log_{2}N) O ( l o g 2 N ) ,空间复杂度为O ( 1 ) O(1) O ( 1 )
[ F ( N ) F ( N − 1 ) ] = [ F ( N − 1 ) + F ( N − 2 ) F ( N − 1 ) ] = [ 1 1 1 0 ] [ F ( N − 1 ) F ( N − 2 ) ] 可以推出: [ F ( N ) F ( N − 1 ) ] = [ 1 1 1 0 ] N − 1 [ F ( 1 ) F ( 0 ) ] \begin{array}{l}
\begin{bmatrix}
F(N)\\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
F(N-1) + F(N-2) \\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix} \begin{bmatrix}
F(N-1) \\
F(N-2)
\end{bmatrix}
\\
\\
可以推出:\\
\begin{bmatrix}
F(N)\\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix}^{N-1} \begin{bmatrix}
F(1)\\
F(0)
\end{bmatrix}
\end{array} [ F ( N ) F ( N − 1 ) ] = [ F ( N − 1 ) + F ( N − 2 ) F ( N − 1 ) ] = [ 1 1 1 0 ] [ F ( N − 1 ) F ( N − 2 ) ] 可以推出: [ F ( N ) F ( N − 1 ) ] = [ 1 1 1 0 ] N − 1 [ F ( 1 ) F ( 0 ) ]
快速幂算法可以快速计算M N M^N M N 在O ( l o g 2 N ) O(log_{2}N) O ( l o g 2 N ) 的时间复杂度内计算得到结果。
快速幂算法源码较长,可以参考实现Github源码
斐波那契数 F ( n ) 是齐次线性递推,根据递推方程 F ( N ) = F ( N − 1 ) + F ( N − 2 ) , 可得到特征方程 x 2 = x + 1 求得 x 1 = 1 + 5 2 , x 1 = 1 − 5 2 , 设通解为 F ( n ) = c 1 x 1 n + c 2 x 2 n 初始值 F ( 0 ) = 0 , F ( 1 ) = 1 ,代入计算得到 c 1 = 1 5 , c 2 = − 1 5 由此得: F ( n ) = 1 5 [ ( 1 + 5 2 ) n − ( 1 − 5 2 ) n ] \begin{array}{l}
斐波那契数F(n)是齐次线性递推,根据递推方程F(N) = F(N-1) + F(N-2),可得到特征方程\\
x^2=x+1
\\
求得x_1=\frac{1+\sqrt{5}}{2},x_1=\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 ]
\end{array} 斐波那契数 F ( n ) 是齐次线性递推,根据递推方程 F ( N ) = F ( N − 1 ) + F ( N − 2 ) , 可得到特征方程 x 2 = x + 1 求得 x 1 = 2 1 + 5 , x 1 = 2 1 − 5 , 设通解为 F ( n ) = c 1 x 1 n + c 2 x 2 n 初始值 F ( 0 ) = 0 , F ( 1 ) = 1 ,代入计算得到 c 1 = 5 1 , c 2 = − 5 1 由此得: F ( n ) = 5 1 [ ( 2 1 + 5 ) n − ( 2 1 − 5 ) n ]
int fib (int n) {
double sqrt5 = sqrt (5 );
double fibN = pow ((1 + sqrt5) / 2 , n) - pow ((1 - sqrt5) / 2 , n);
return round (fibN / sqrt5);
}
类似扩展
LeetCode 70:爬楼梯问题 设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。
这就是一个斐波那契额数列问题,状态转移方程:F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n)=F(n-1)+F(n-2) F ( n ) = F ( n − 1 ) + F ( n − 2 )
快速幂算法递归公式
[ F ( N ) F ( N − 1 ) ] = [ F ( N − 1 ) + F ( N − 2 ) F ( N − 1 ) ] = [ 1 1 1 0 ] [ F ( N − 1 ) F ( N − 2 ) ] 可以推出: [ F ( N ) F ( N − 1 ) ] = [ 1 1 1 0 ] N − 1 [ F ( 1 ) F ( 0 ) ] \begin{array}{l}
\begin{bmatrix}
F(N)\\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
F(N-1) + F(N-2) \\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix} \begin{bmatrix}
F(N-1) \\
F(N-2)
\end{bmatrix}
\\
\\
可以推出:\\
\begin{bmatrix}
F(N)\\
F(N-1)
\end{bmatrix} = \begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix}^{N-1} \begin{bmatrix}
F(1)\\
F(0)
\end{bmatrix}
\end{array} [ F ( N ) F ( N − 1 ) ] = [ F ( N − 1 ) + F ( N − 2 ) F ( N − 1 ) ] = [ 1 1 1 0 ] [ F ( N − 1 ) F ( N − 2 ) ] 可以推出: [ F ( N ) F ( N − 1 ) ] = [ 1 1 1 0 ] N − 1 [ F ( 1 ) F ( 0 ) ]
实现github源码
LeetCode1137 第 N 个泰波那契数 泰波那契序列 Tn 定义如下: T0=0, T1=1, T2=1, 且在n>= 0 的条件下Tn+3=Tn+Tn+1+Tn+2。给你整数n,请返回第n个泰波那契数Tn的值
快速幂算法递归公式
[ T n T n − 1 T n − 2 ] = [ T n − 3 + T n − 2 + T n − 1 T n − 1 T n − 2 ] = [ 1 1 1 1 0 0 0 1 0 ] [ T n − 1 T n − 2 T n − 3 ] 从而,可以推出: [ T n T n − 1 T n − 2 ] = ( [ 1 1 1 1 0 0 0 1 0 ] ) n − 2 [ T 2 T 1 T 0 ] 其中: T 0 = 0 , T 1 = 1 , T 2 = 1 \begin{array}{l}
\begin{bmatrix}
T_n\\
T_{n-1}\\
T_{n-2}
\end{bmatrix} = \begin{bmatrix}
T_{n-3} + T_{n-2} + T_{n-1}\\
T_{n-1}\\
T_{n-2}
\end{bmatrix} = \begin{bmatrix}
1 & 1 & 1 \\
1 & 0 & 0 \\
0 & 1 & 0
\end{bmatrix} \begin{bmatrix}
T_{n-1} \\
T_{n-2} \\
T_{n-3}
\end{bmatrix}
\\
\\
从而,可以推出:\\
\begin{bmatrix}
T_n\\
T_{n-1}\\
T_{n-2}
\end{bmatrix} = \left (\begin{bmatrix}
1 & 1 & 1 \\
1 & 0 & 0 \\
0 & 1 & 0
\end{bmatrix} \right )^{n-2}\begin{bmatrix}
T_2\\
T_{1}\\
T_{0}
\end{bmatrix} \\
\\
其中:T_0=0, T_1=1, T_2=1
\end{array} ⎣ ⎡ T n T n − 1 T n − 2 ⎦ ⎤ = ⎣ ⎡ T n − 3 + T n − 2 + T n − 1 T n − 1 T n − 2 ⎦ ⎤ = ⎣ ⎡ 1 1 0 1 0 1 1 0 0 ⎦ ⎤ ⎣ ⎡ T n − 1 T n − 2 T n − 3 ⎦ ⎤ 从而,可以推出: ⎣ ⎡ T n T n − 1 T n − 2 ⎦ ⎤ = ⎝ ⎛ ⎣ ⎡ 1 1 0 1 0 1 1 0 0 ⎦ ⎤ ⎠ ⎞ n − 2 ⎣ ⎡ T 2 T 1 T 0 ⎦ ⎤ 其中: T 0 = 0 , T 1 = 1 , T 2 = 1
动态规划和快速幂等实现github源码
参考资料
《程序员代码面试指南:IT名企算法与数据结构题目最优解(第2版)》