给定数字n,找到第n个斐波那契数。请注意,F0 = 0,F1 = 1,F2 = 2,…。
例子 :
Input : n = 5
Output : 5
Input : n = 10
Output : 89
我们在下面的斐波那契数字程序的方法4中讨论了递归解决方案。
F[2][2] = |1, 1|
|1, 0|
M[2][2] = |1, 1|
|1, 0|
F[n][n] = fib(n) | fib(n-1)
------------------
fib(n-1)| fib(n-2)
在本文中,我们讨论了一种迭代方法,该方法避免了额外的递归调用堆栈空间。我们还使用了按位运算运算符来进一步优化。在前面的方法中,我们将数字除以2,这样最后得到1,然后开始乘法过程
在这种方法中,我们得到第二个MSB,然后开始与FxF矩阵相乘,然后如果设置了位,则再次与FxM矩阵相乘,依此类推。然后我们得到最终结果。
Approach :
1. First get the MSB of a number.
2. while (MSB > 0)
multiply(F, F);
if (n & MSB)
multiply(F, M);
and then shift MSB till MSB != 0
C++
// CPP code to find nth fibonacci
#include
using namespace std;
// get second MSB
int getMSB(int n)
{
// consectutively set all the bits
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
// returns the second MSB
return ((n + 1) >> 2);
}
// Multiply function
void multiply(int F[2][2], int M[2][2])
{
int x = F[0][0] * M[0][0] + F[0][1] * M[1][0];
int y = F[0][0] * M[0][1] + F[0][1] * M[1][1];
int z = F[1][0] * M[0][0] + F[1][1] * M[1][0];
int w = F[1][0] * M[0][1] + F[1][1] * M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
// Function to calculate F[][]
// raise to the power n
void power(int F[2][2], int n)
{
// Base case
if (n == 0 || n == 1)
return;
// take 2D array to store number's
int M[2][2] = { 1, 1, 1, 0 };
// run loop till MSB > 0
for (int m = getMSB(n); m; m = m >> 1) {
multiply(F, F);
if (n & m) {
multiply(F, M);
}
}
}
// To return fibonacci numebr
int fib(int n)
{
int F[2][2] = { { 1, 1 }, { 1, 0 } };
if (n == 0)
return 0;
power(F, n - 1);
return F[0][0];
}
// Driver Code
int main()
{
// Given n
int n = 6;
cout << fib(n) << " ";
return 0;
}
Java
// Java code to
// find nth fibonacci
class GFG
{
// get second MSB
static int getMSB(int n)
{
// consectutively set
// all the bits
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
// returns the
// second MSB
return ((n + 1) >> 2);
}
// Multiply function
static void multiply(int F[][],
int M[][])
{
int x = F[0][0] * M[0][0] +
F[0][1] * M[1][0];
int y = F[0][0] * M[0][1] +
F[0][1] * M[1][1];
int z = F[1][0] * M[0][0] +
F[1][1] * M[1][0];
int w = F[1][0] * M[0][1] +
F[1][1] * M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
// Function to calculate F[][]
// raise to the power n
static void power(int F[][],
int n)
{
// Base case
if (n == 0 || n == 1)
return;
// take 2D array to
// store number's
int[][] M ={{1, 1},
{1, 0}};
// run loop till MSB > 0
for (int m = getMSB(n);
m > 0; m = m >> 1)
{
multiply(F, F);
if ((n & m) > 0)
{
multiply(F, M);
}
}
}
// To return
// fibonacci numebr
static int fib(int n)
{
int[][] F = {{1, 1},
{1, 0}};
if (n == 0)
return 0;
power(F, n - 1);
return F[0][0];
}
// Driver Code
public static void main(String[] args)
{
// Given n
int n = 6;
System.out.println(fib(n));
}
}
// This code is contributed
// by mits
Python3
# Python3 code to find nth fibonacci
# get second MSB
def getMSB(n):
# consectutively set all the bits
n |= n >> 1
n |= n >> 2
n |= n >> 4
n |= n >> 8
n |= n >> 16
# returns the second MSB
return ((n + 1) >> 2)
# Multiply function
def multiply(F, M):
x = F[0][0] * M[0][0] + F[0][1] * M[1][0]
y = F[0][0] * M[0][1] + F[0][1] * M[1][1]
z = F[1][0] * M[0][0] + F[1][1] * M[1][0]
w = F[1][0] * M[0][1] + F[1][1] * M[1][1]
F[0][0] = x
F[0][1] = y
F[1][0] = z
F[1][1] = w
# Function to calculate F[][]
# raise to the power n
def power(F, n):
# Base case
if (n == 0 or n == 1):
return
# take 2D array to store number's
M = [[1, 1], [1, 0]]
# run loop till MSB > 0
m = getMSB(n)
while m:
multiply(F, F)
if (n & m):
multiply(F, M)
m = m >> 1
# To return fibonacci numebr
def fib(n):
F = [[1, 1 ], [1, 0 ]]
if (n == 0):
return 0
power(F, n - 1)
return F[0][0]
# Driver Code
# Given n
n = 6
print(fib(n))
# This code is contributed by Mohit Kumar
C#
// C# code to find nth fibonacci
using System;
class GFG {
// get second MSB
static int getMSB(int n)
{
// consectutively set
// all the bits
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
// returns the
// second MSB
return ((n + 1) >> 2);
}
// Multiply function
static void multiply(int [,]F,
int [,]M)
{
int x = F[0,0] * M[0,0] +
F[0,1] * M[1,0];
int y = F[0,0] * M[0,1] +
F[0,1] * M[1,1];
int z = F[1,0] * M[0,0] +
F[1,1] * M[1,0];
int w = F[1,0] * M[0,1] +
F[1,1] * M[1,1];
F[0,0] = x;
F[0,1] = y;
F[1,0] = z;
F[1,1] = w;
}
// Function to calculate F[][]
// raise to the power n
static void power(int [,]F,
int n)
{
// Base case
if (n == 0 || n == 1)
return;
// take 2D array to
// store number's
int[,] M ={{1, 1},
{1, 0}};
// run loop till MSB > 0
for (int m = getMSB(n);
m > 0; m = m >> 1)
{
multiply(F, F);
if ((n & m) > 0)
{
multiply(F, M);
}
}
}
// To return
// fibonacci numebr
static int fib(int n)
{
int[,] F = {{1, 1},
{1, 0}};
if (n == 0)
return 0;
power(F, n - 1);
return F[0,0];
}
// Driver Code
static public void Main ()
{
// Given n
int n = 6;
Console.WriteLine(fib(n));
}
}
// This code is contributed ajit
PHP
> 1;
$n |= $n >> 2;
$n |= $n >> 4;
$n |= $n >> 8;
$n |= $n >> 16;
// returns the second MSB
return (($n + 1) >> 2);
}
// Multiply function
function multiply(&$F, &$M)
{
$x = $F[0][0] * $M[0][0] +
$F[0][1] * $M[1][0];
$y = $F[0][0] * $M[0][1] +
$F[0][1] * $M[1][1];
$z = $F[1][0] * $M[0][0] +
$F[1][1] * $M[1][0];
$w = $F[1][0] * $M[0][1] +
$F[1][1] * $M[1][1];
$F[0][0] = $x;
$F[0][1] = $y;
$F[1][0] = $z;
$F[1][1] = $w;
}
// Function to calculate F[][]
// raise to the power n
function power(&$F, $n)
{
// Base case
if ($n == 0 || $n == 1)
return;
// take 2D array to store number's
$M = array(array(1, 1), array(1, 0));
// run loop till MSB > 0
for ($m = getMSB($n); $m; $m = $m >> 1)
{
multiply($F, $F);
if ($n & $m)
{
multiply($F, $M);
}
}
}
// To return fibonacci numebr
function fib($n)
{
$F = array(array( 1, 1 ),
array( 1, 0 ));
if ($n == 0)
return 0;
power($F, $n - 1);
return $F[0][0];
}
// Driver Code
// Given n
$n = 6;
echo fib($n) . " ";
// This code is contributed by ita_c
?>
输出:
8
时间复杂度: -O(logn)和空间复杂度: -O(1)。