Space efficient iterative method to Fibonacci number
Given a number n, find n-th Fibonacci Number. Note that F0 = 0, F1 = 1, F2 = 2, …..
Examples :
Input : n = 5
Output : 5
Input : n = 10
Output : 89
We have discussed below recursive solution in method 4 of Program for Fibonacci numbers.
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)
In this post an iterative method is discussed that avoids extra recursion call stack space. We have also used bitwise operators to further optimize. In the previous method, we divide the number with 2 so that at the end we get 1 and then we start the multiplication process
In this method we get the second MSB then start to multiply with FxF matrix then if bit is set then multiply again FxM matrix and so on. then we get the final result.
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++
#include <bits/stdc++.h>
using namespace std;
int getMSB( int n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return ((n + 1) >> 2);
}
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;
}
void power( int F[2][2], int n)
{
if (n == 0 || n == 1)
return ;
int M[2][2] = { 1, 1, 1, 0 };
for ( int m = getMSB(n); m; m = m >> 1) {
multiply(F, F);
if (n & m) {
multiply(F, M);
}
}
}
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];
}
int main()
{
int n = 6;
cout << fib(n) << " " ;
return 0;
}
|
Java
class GFG
{
static int getMSB( int n)
{
n |= n >> 1 ;
n |= n >> 2 ;
n |= n >> 4 ;
n |= n >> 8 ;
n |= n >> 16 ;
return ((n + 1 ) >> 2 );
}
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;
}
static void power( int F[][],
int n)
{
if (n == 0 || n == 1 )
return ;
int [][] M ={{ 1 , 1 },
{ 1 , 0 }};
for ( int m = getMSB(n);
m > 0 ; m = m >> 1 )
{
multiply(F, F);
if ((n & m) > 0 )
{
multiply(F, M);
}
}
}
static int fib( int n)
{
int [][] F = {{ 1 , 1 },
{ 1 , 0 }};
if (n == 0 )
return 0 ;
power(F, n - 1 );
return F[ 0 ][ 0 ];
}
public static void main(String[] args)
{
int n = 6 ;
System.out.println(fib(n));
}
}
|
Python3
def getMSB(n):
n | = n >> 1
n | = n >> 2
n | = n >> 4
n | = n >> 8
n | = n >> 16
return ((n + 1 ) >> 2 )
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
def power(F, n):
if (n = = 0 or n = = 1 ):
return
M = [[ 1 , 1 ], [ 1 , 0 ]]
m = getMSB(n)
while m:
multiply(F, F)
if (n & m):
multiply(F, M)
m = m >> 1
def fib(n):
F = [[ 1 , 1 ], [ 1 , 0 ]]
if (n = = 0 ):
return 0
power(F, n - 1 )
return F[ 0 ][ 0 ]
n = 6
print (fib(n))
|
C#
using System;
class GFG {
static int getMSB( int n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return ((n + 1) >> 2);
}
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;
}
static void power( int [,]F,
int n)
{
if (n == 0 || n == 1)
return ;
int [,] M ={{1, 1},
{1, 0}};
for ( int m = getMSB(n);
m > 0; m = m >> 1)
{
multiply(F, F);
if ((n & m) > 0)
{
multiply(F, M);
}
}
}
static int fib( int n)
{
int [,] F = {{1, 1},
{1, 0}};
if (n == 0)
return 0;
power(F, n - 1);
return F[0,0];
}
static public void Main ()
{
int n = 6;
Console.WriteLine(fib(n));
}
}
|
PHP
<?php
function getMSB( $n )
{
$n |= $n >> 1;
$n |= $n >> 2;
$n |= $n >> 4;
$n |= $n >> 8;
$n |= $n >> 16;
return (( $n + 1) >> 2);
}
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 power(& $F , $n )
{
if ( $n == 0 || $n == 1)
return ;
$M = array ( array (1, 1), array (1, 0));
for ( $m = getMSB( $n ); $m ; $m = $m >> 1)
{
multiply( $F , $F );
if ( $n & $m )
{
multiply( $F , $M );
}
}
}
function fib( $n )
{
$F = array ( array ( 1, 1 ),
array ( 1, 0 ));
if ( $n == 0)
return 0;
power( $F , $n - 1);
return $F [0][0];
}
$n = 6;
echo fib( $n ) . " " ;
?>
|
Javascript
<script>
function getMSB(n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return ((n + 1) >> 2);
}
function multiply(F, M)
{
let x = F[0][0] * M[0][0] +
F[0][1] * M[1][0];
let y = F[0][0] * M[0][1] +
F[0][1] * M[1][1];
let z = F[1][0] * M[0][0] +
F[1][1] * M[1][0];
let 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 power(F, n)
{
if (n == 0 || n == 1)
return ;
let M = [ [ 1, 1 ], [ 1, 0 ] ];
for (let m = getMSB(n); m > 0; m = m >> 1)
{
multiply(F, F);
if ((n & m) > 0)
{
multiply(F, M);
}
}
}
function fib(n)
{
let F = [ [ 1, 1 ], [ 1, 0 ] ];
if (n == 0)
return 0;
power(F, n - 1);
return F[0][0];
}
let n = 6;
document.write(fib(n));
</script>
|
Time Complexity :- O(logn) and space complexity :- O(1).
Last Updated :
20 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...