给定整数N ,任务是找到第N个斐波那契数。
例子:
Input: N = 3
Output: 2
Explanation:
F(1) = 1, F(2) = 1
F(3) = F(1) + F(2) = 2
Input: N = 6
Output: 8
方法:
- 矩阵求幂方法已经在前面讨论过了。尽管不使用矩阵乘法本身,但加倍方法可以看作是对求第N个斐波那契数的矩阵求幂方法的一种改进。
- 斐波那契递归序列由下式给出
F(n+1) = F(n) + F(n-1)
- 矩阵幂方法使用以下公式
- 该方法涉及昂贵的矩阵乘法,而且F n被重复计算两次。
另一方面,快速加倍方法基于两个基本公式:
F(2n) = F(n)[2F(n+1) – F(n)]
F(2n + 1) = F(n)2 + F(n+1)2
- 这是上述结果的简短说明:
Start with:
F(n+1) = F(n) + F(n-1) &
F(n) = F(n)
It can be rewritten in the matrix form as:
For doubling, we just plug in “2n” into the formula:
Substituting F(n-1) = F(n+1)- F(n) and after simplification we get,
下面是上述方法的实现:
C++
// C++ program to find the Nth Fibonacci
// number using Fast Doubling Method
#include
using namespace std;
int a, b, c, d;
#define MOD 1000000007
// Function calculate the N-th fibanacci
// number using fast doubling method
void FastDoubling(int n, int res[])
{
// Base Condition
if (n == 0) {
res[0] = 0;
res[1] = 1;
return;
}
FastDoubling((n / 2), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0) {
res[0] = c;
res[1] = d;
}
else {
res[0] = d;
res[1] = c + d;
}
}
// Driver code
int main()
{
int N = 6;
int res[2] = { 0 };
FastDoubling(N, res);
cout << res[0] << "\n";
return 0;
}
Java
// Java program to find the Nth Fibonacci
// number using Fast Doubling Method
class GFG{
// Function calculate the N-th fibanacci
// number using fast doubling method
static void FastDoubling(int n, int []res)
{
int a, b, c, d;
int MOD = 1000000007;
// Base Condition
if (n == 0)
{
res[0] = 0;
res[1] = 1;
return;
}
FastDoubling((n / 2), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0)
{
res[0] = c;
res[1] = d;
}
else
{
res[0] = d;
res[1] = c + d;
}
}
// Driver code
public static void main(String []args)
{
int N = 6;
int res[] = new int[2];
FastDoubling(N, res);
System.out.print(res[0]);
}
}
// This code is contributed by rock_cool
Python3
# Python3 program to find the Nth Fibonacci
# number using Fast Doubling Method
MOD = 1000000007
# Function calculate the N-th fibanacci
# number using fast doubling method
def FastDoubling(n, res):
# Base Condition
if (n == 0):
res[0] = 0
res[1] = 1
return
FastDoubling((n // 2), res)
# Here a = F(n)
a = res[0]
# Here b = F(n+1)
b = res[1]
c = 2 * b - a
if (c < 0):
c += MOD
# As F(2n) = F(n)[2F(n+1) – F(n)]
# Here c = F(2n)
c = (a * c) % MOD
# As F(2n + 1) = F(n)^2 + F(n+1)^2
# Here d = F(2n + 1)
d = (a * a + b * b) % MOD
# Check if N is odd
# or even
if (n % 2 == 0):
res[0] = c
res[1] = d
else :
res[0] = d
res[1] = c + d
# Driver code
N = 6
res = [0] * 2
FastDoubling(N, res)
print(res[0])
# This code is contributed by divyamohan123
C#
// C# program to find the Nth Fibonacci
// number using Fast Doubling Method
using System;
class GFG{
// Function calculate the N-th fibanacci
// number using fast doubling method
static void FastDoubling(int n, int []res)
{
int a, b, c, d;
int MOD = 1000000007;
// Base Condition
if (n == 0)
{
res[0] = 0;
res[1] = 1;
return;
}
FastDoubling((n / 2), res);
// Here a = F(n)
a = res[0];
// Here b = F(n+1)
b = res[1];
c = 2 * b - a;
if (c < 0)
c += MOD;
// As F(2n) = F(n)[2F(n+1) – F(n)]
// Here c = F(2n)
c = (a * c) % MOD;
// As F(2n + 1) = F(n)^2 + F(n+1)^2
// Here d = F(2n + 1)
d = (a * a + b * b) % MOD;
// Check if N is odd
// or even
if (n % 2 == 0)
{
res[0] = c;
res[1] = d;
}
else
{
res[0] = d;
res[1] = c + d;
}
}
// Driver code
public static void Main()
{
int N = 6;
int []res = new int[2];
FastDoubling(N, res);
Console.Write(res[0]);
}
}
// This code is contributed by Code_Mech
Javascript
输出:
8
时间复杂度:重复平方减少了从线性到对数的时间。因此,使用恒定时间算法,时间复杂度为O(log n) 。