Given a positive integer n, find the nth Fibonacci number.
The Fibonacci series is a sequence where a term is the sum of previous two terms. The first two terms of the Fibonacci sequence are 0 followed by 1. The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21.
Example:
Input: n = 2
Output: 1
Explanation: 1 is the 2nd number of Fibonacci series.Input: n = 5
Output: 5
Explanation: 5 is the 5th number of Fibonacci series.
Table of Content
[Naive Approach] Using Recursion
We can use recursion to solve this problem because any Fibonacci number n depends on previous two Fibonacci numbers. Therefore, this approach repeatedly breaks down the problem until it reaches the base cases.
Recurrence relation:
- Base case: F(n) = n, when n = 0 or n = 1
- Recursive case: F(n) = F(n-1) + F(n-2) for n>1
//Driver Code Starts
#include <iostream>
using namespace std;
//Driver Code Ends
int nthFibonacci(int n){
// base case
if (n <= 1){
return n;
}
// sum of the two preceding
// Fibonacci numbers
return nthFibonacci(n - 1) + nthFibonacci(n - 2);
}
//Driver Code Starts
int main(){
int n = 5;
int result = nthFibonacci(n);
cout << result << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
#include <stdio.h>
//Driver Code Ends
int nthFibonacci(int n) {
// base case
if (n <= 1){
return n;
}
// sum of the two preceding
// Fibonacci numbers
return nthFibonacci(n - 1) + nthFibonacci(n - 2);
}
//Driver Code Starts
int main(){
int n = 5;
int result = nthFibonacci(n);
printf("%d
", result);
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GFG {
//Driver Code Ends
static int nthFibonacci(int n){
// base case
if (n <= 1) {
return n;
}
// sum of the two preceding
// Fibonacci numbers
return nthFibonacci(n - 1) + nthFibonacci(n - 2);
}
//Driver Code Starts
public static void main(String[] args){
int n = 5;
int result = nthFibonacci(n);
System.out.println(result);
}
}
//Driver Code Ends
def nth_fibonacci(n):
# base case
if n <= 1:
return n
# sum of the two preceding
# Fibonacci numbers
return nth_fibonacci(n - 1) + nth_fibonacci(n - 2)
#Driver Code Starts
n = 5
result = nth_fibonacci(n)
print(result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int nthFibonacci(int n){
// base case
if (n <= 1) {
return n;
}
// sum of the two preceding
// Fibonacci numbers
return nthFibonacci(n - 1) + nthFibonacci(n - 2);
}
//Driver Code Starts
static void Main(){
int n = 5;
int result = nthFibonacci(n);
Console.WriteLine(result);
}
}
//Driver Code Ends
function nthFibonacci(n){
// base case
if (n <= 1) {
return n;
}
// sum of the two preceding
// Fibonacci numbers
return nthFibonacci(n - 1) + nthFibonacci(n - 2);
}
//Driver Code Starts
let n = 5;
let result = nthFibonacci(n);
console.log(result);
//Driver Code Ends
Output
5
Time Complexity: O(2n), because each state requires answers from previous two states, and thus calls the function for both of those states recursively.
Auxiliary Space: O(n), due to recursion stack
[Expected Approach-1] Memoization Approach
The idea is to optimize the recursive solution by storing the results of already solved subproblems in a memoization table. Whenever the same subproblem appears again, we reuse the stored result instead of recomputing it. This avoids repeated calculations and improves the overall efficiency, reducing the time complexity from exponential to linear.

//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
int nthFibonacciUtil(int n, vector<int>& dp) {
// Base case
if (n <= 1) {
return n;
}
// Check if the result is
// already in the dp table
if (dp[n] != -1) {
return dp[n];
}
// calculate Fibonacci number
// and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp)
+ nthFibonacciUtil(n - 2, dp);
return dp[n];
}
int nthFibonacci(int n) {
// Create a dp table and
// initialize with -1(invalid value)
vector<int> dp(n + 1, -1);
return nthFibonacciUtil(n, dp);
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
cout << result;
}
//Driver Code Ends
//Driver Code Starts
#include <stdio.h>
//Driver Code Ends
int nthFibonacciUtil(int n, int dp[]) {
// Base case
if (n <= 1) {
return n;
}
// Check if the result is
// already in the dp table
if (dp[n] != -1) {
return dp[n];
}
// calculate Fibonacci number
// and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp)
+ nthFibonacciUtil(n - 2, dp);
return dp[n];
}
int nthFibonacci(int n) {
// Create a dp table and
// initialize with -1(invalid value)
int dp[n + 1];
for (int i = 0; i <= n; i++) dp[i] = -1;
return nthFibonacciUtil(n, dp);
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
printf("%d", result);
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.Arrays;
class GFG {
//Driver Code Ends
static int nthFibonacciUtil(int n, int[] dp) {
// Base case
if (n <= 1) {
return n;
}
// Check if the result is
// already in the dp table
if (dp[n] != -1) {
return dp[n];
}
// calculate Fibonacci number
// and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp)
+ nthFibonacciUtil(n - 2, dp);
return dp[n];
}
static int nthFibonacci(int n) {
// Create a dp table and
// initialize with -1(invalid value)
int[] dp = new int[n + 1];
Arrays.fill(dp, -1);
return nthFibonacciUtil(n, dp);
}
//Driver Code Starts
public static void main(String[] args) {
int n = 5;
int result = nthFibonacci(n);
System.out.println(result);
}
}
//Driver Code Ends
def nthFibonacciUtil(n, dp):
# Base case
if n <= 1:
return n
# Check if the result is
# already in the dp table
if dp[n] != -1:
return dp[n]
# calculate Fibonacci number
# and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp) + nthFibonacciUtil(n - 2, dp)
return dp[n]
def nthFibonacci(n):
# Create a dp table and
# initialize with -1(invalid value)
dp = [-1] * (n + 1)
return nthFibonacciUtil(n, dp)
#Driver Code Starts
if __name__ == "__main__":
n = 5
result = nthFibonacci(n)
print(result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int nthFibonacciUtil(int n, int[] dp) {
// Base case
if (n <= 1) {
return n;
}
// Check if the result is
// already in the dp table
if (dp[n] != -1) {
return dp[n];
}
// calculate Fibonacci number
// and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp)
+ nthFibonacciUtil(n - 2, dp);
return dp[n];
}
static int nthFibonacci(int n) {
// Create a dp table and
// initialize with -1(invalid value)
int[] dp = new int[n + 1];
for (int i = 0; i <= n; i++) dp[i] = -1;
return nthFibonacciUtil(n, dp);
}
//Driver Code Starts
static void Main() {
int n = 5;
int result = nthFibonacci(n);
Console.WriteLine(result);
}
}
//Driver Code Ends
function nthFibonacciUtil(n, dp) {
// Base case
if (n <= 1) {
return n;
}
// Check if the result is
// already in the dp table
if (dp[n] !== -1) {
return dp[n];
}
// calculate Fibonacci number
// and store it in dp table
dp[n] = nthFibonacciUtil(n - 1, dp)
+ nthFibonacciUtil(n - 2, dp);
return dp[n];
}
function nthFibonacci(n) {
// Create a dp table and
// initialize with -1(invalid value)
const dp = new Array(n + 1).fill(-1);
return nthFibonacciUtil(n, dp);
}
//Driver Code Starts
// Driver code
const n = 5;
const result = nthFibonacci(n);
console.log(result);
//Driver Code Ends
Output
5
Time Complexity: O(n), each Fibonacci number is calculated only one time,
Auxiliary Space: O(n), for dp table.
[Expected Approach-2] Bottom-Up Approach
In this approach, we are iteratively calculating the answers from the bottom up, beginning with the smallest subproblems, the first two Fibonacci numbers 0 and 1. Using these initial values, we generate the next numbers one by one by adding the previous two results. Each value is calculated only once and reused later, so no repeated work is done. This method avoids recursion and makes the solution simple and efficient with linear time complexity.
- Start with the base values fib(0) = 0 and fib(1) = 1.
- Initialize variables or an array to store these initial results.
- Iterate from index 2 up to n.
- At each step compute fib(i) as fib(i-1) + fib(i-2).
- Continue until the nth Fibonacci number is obtained.
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
int nthFibonacci(int n){
// base cases
if (n <= 1)
return n;
vector<int> dp(n + 1);
dp[0] = 0; dp[1] = 1;
// solving the smaller problems first
// and finally solving the complete problem
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
//Driver Code Starts
int main(){
int n = 5;
int result = nthFibonacci(n);
cout << result << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
#include <stdio.h>
//Driver Code Ends
int nthFibonacci(int n) {
// base cases
if (n <= 1) return n;
int dp[n + 1];
dp[0] = 0;
dp[1] = 1;
// solving the smaller problems first
// and finally solving the complete problem
for (int i = 2; i <= n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
printf("%d
", result);
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GFG {
//Driver Code Ends
static int nthFibonacci(int n) {
// base cases
if (n <= 1) return n;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
// solving the smaller problems first
// and finally solving the complete problem
for (int i = 2; i <= n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
//Driver Code Starts
public static void main(String[] args) {
int n = 5;
int result = nthFibonacci(n);
System.out.println(result);
}
}
//Driver Code Ends
def nthFibonacci(n):
if n <= 1:
return n
dp = [0] * (n + 1)
dp[0], dp[1] = 0, 1
# solving the smaller problems first
# and finally solving the complete problem
for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
#Driver Code Starts
if __name__ == "__main__":
n = 5
result = nthFibonacci(n)
print(result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
public static int nthFibonacci(int n) {
if (n <= 1) return n;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
// solving the smaller problems first
// and finally solving the complete problem
for (int i = 2; i <= n; ++i) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
//Driver Code Starts
static void Main() {
int n = 5;
int result = nthFibonacci(n);
Console.WriteLine(result);
}
}
//Driver Code Ends
function nthFibonacci(n) {
// base cases
if (n <= 1) return n;
let dp = new Array(n + 1);
dp[0] = 0;
dp[1] = 1;
// solving the smaller problems first
// and finally solving the complete problem
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
//Driver Code Starts
// Driver code
let n = 5;
let result = nthFibonacci(n);
console.log(result);
//Driver Code Ends
Output
5
Time Complexity: O(n), each fibonacci number is calculated only one time,
Auxiliary Space: O(n), for dp table.
[Expected Approach-3] Bottom Up Space Optimized Approach - O(n) Time and O(1) Space
In this approach, we store the results of the previous two states, and as we move forward, we update them to compute the next values. This means keeping track of the last two Fibonacci numbers and using them to calculate the next one, efficiently covering all states without needing extra space for a full DP table.
//Driver Code Starts
#include <iostream>
using namespace std;
//Driver Code Ends
int nthFibonacci(int n){
if (n <= 1) return n;
// stores current Fibonacci number
int curr = 0;
// To store the previous
// two Fibonacci numbers
int prev1 = 1;
int prev2 = 0;
for (int i = 2; i <= n; i++) {
curr = prev1 + prev2;
// Update previous two Fibonacci
// numbers for next number
prev2 = prev1;
prev1 = curr;
}
return curr;
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
cout << result << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
#include <stdio.h>
//Driver Code Ends
int nthFibonacci(int n) {
if (n <= 1) return n;
// stores current Fibonacci number
int curr = 0;
// To store the previous
// two Fibonacci numbers
int prev1 = 1;
int prev2 = 0;
for (int i = 2; i <= n; i++) {
curr = prev1 + prev2;
// Update previous two Fibonacci
// numbers for next number
prev2 = prev1;
prev1 = curr;
}
return curr;
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
printf("%d
", result);
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GFG {
//Driver Code Ends
static int nthFibonacci(int n) {
if (n <= 1) return n;
// stores current Fibonacci number
int curr = 0;
// To store the previous
// two Fibonacci numbers
int prev1 = 1;
int prev2 = 0;
for (int i = 2; i <= n; i++) {
curr = prev1 + prev2;
// Update previous two Fibonacci
// numbers for next number
prev2 = prev1;
prev1 = curr;
}
return curr;
}
//Driver Code Starts
public static void main(String[] args) {
int n = 5;
int result = nthFibonacci(n);
System.out.println(result);
}
}
//Driver Code Ends
def nthFibonacci(n):
if n <= 1:
return n
# stores current Fibonacci number
curr = 0
# To store the previous
# two Fibonacci numbers
prev1 = 1
prev2 = 0
for i in range(2, n + 1):
curr = prev1 + prev2
# Update previous two Fibonacci
# numbers for next number
prev2 = prev1
prev1 = curr
return curr
#Driver Code Starts
if __name__ == "__main__":
n = 5
result = nthFibonacci(n)
print(result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
public static int nthFibonacci(int n) {
if (n <= 1) return n;
// stores current Fibonacci number
int curr = 0;
// To store the previous
// two Fibonacci numbers
int prev1 = 1;
int prev2 = 0;
for (int i = 2; i <= n; i++) {
curr = prev1 + prev2;
// Update previous two Fibonacci
// numbers for next number
prev2 = prev1;
prev1 = curr;
}
return curr;
}
//Driver Code Starts
static void Main() {
int n = 5;
int result = nthFibonacci(n);
Console.WriteLine(result);
}
}
//Driver Code Ends
function nthFibonacci(n) {
if (n <= 1) return n;
// stores current Fibonacci number
let curr = 0;
// To store the previous
// two Fibonacci numbers
let prev1 = 1;
let prev2 = 0;
for (let i = 2; i <= n; i++) {
curr = prev1 + prev2;
// Update previous two Fibonacci
// numbers for next number
prev2 = prev1;
prev1 = curr;
}
return curr;
}
//Driver Code Starts
// Driver code
let n = 5;
let result = nthFibonacci(n);
console.log(result);
//Driver Code Ends
Output
5
Using Matrix Exponentiation - O(log(n)) time and O(log(n)) space
In this approach, we observe that Fibonacci number is the sum of previous two Fibonacci numbers. this could be done by adding numbers repeatedly or use loops or recursion, which takes time. But with matrix exponentiation, we can calculateFibonacci numbers much faster by working with matrices. There's a special matrix (transformation matrix) that represents how Fibonacci numbers work.
It looks like this:
To find the Nth Fibonacci number we need to multiply transformation matrix (n-1) times, the matrix equation for the Fibonacci sequence looks like:
After raising the transformation matrix to the power n - 1, the top-left element F(n) will give the nth Fibonacci number.
//Driver Code Starts
#include <vector>
#include <iostream>
using namespace std;
//Driver Code Ends
void multiply(vector<vector<int>>& mat1,
vector<vector<int>>& mat2) {
int x = mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0];
int y = mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1];
int z = mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0];
int w = mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1];
// Update matrix mat1 with the result
mat1[0][0] = x;
mat1[0][1] = y;
mat1[1][0] = z;
mat1[1][1] = w;
}
void matrixPower(vector<vector<int>>& mat1, int n) {
// Base case for recursion
if (n == 0 || n == 1) return;
vector<vector<int>> mat2 = {{1, 1}, {1, 0}};
matrixPower(mat1, n / 2);
multiply(mat1, mat1);
// If n is odd, multiply by the helper matrix mat2
if (n % 2 != 0) {
multiply(mat1, mat2);
}
}
int nthFibonacci(int n) {
if (n <= 1) return n;
// Initialize the transformation matrix
vector<vector<int>> mat1 = {{1, 1}, {1, 0}};
matrixPower(mat1, n - 1);
// The result is in the top-left cell of the matrix
return mat1[0][0];
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
cout << result << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
#include <stdio.h>
//Driver Code Ends
void multiply(int mat1[2][2], int mat2[2][2]) {
int x = mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0];
int y = mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1];
int z = mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0];
int w = mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1];
// Update matrix mat1 with the result
mat1[0][0] = x;
mat1[0][1] = y;
mat1[1][0] = z;
mat1[1][1] = w;
}
void matrixPower(int mat1[2][2], int n) {
// Base case for recursion
if (n == 0 || n == 1) return;
int mat2[2][2] = {{1, 1}, {1, 0}};
matrixPower(mat1, n / 2);
multiply(mat1, mat1);
// If n is odd, multiply by the helper matrix mat2
if (n % 2 != 0) {
multiply(mat1, mat2);
}
}
int nthFibonacci(int n) {
if (n <= 1) return n;
// Initialize the transformation matrix
int mat1[2][2] = {{1, 1}, {1, 0}};
matrixPower(mat1, n - 1);
// The result is in the top-left cell of the matrix
return mat1[0][0];
}
//Driver Code Starts
int main() {
int n = 5;
int result = nthFibonacci(n);
printf("%d
", result);
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GFG {
//Driver Code Ends
static void multiply(int[][] mat1, int[][] mat2) {
int x = mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0];
int y = mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1];
int z = mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0];
int w = mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1];
// Update matrix mat1 with the result
mat1[0][0] = x;
mat1[0][1] = y;
mat1[1][0] = z;
mat1[1][1] = w;
}
static void matrixPower(int[][] mat1, int n) {
// Base case for recursion
if (n == 0 || n == 1) return;
int[][] mat2 = {{1, 1}, {1, 0}};
matrixPower(mat1, n / 2);
multiply(mat1, mat1);
// If n is odd, multiply by the helper matrix mat2
if (n % 2 != 0) {
multiply(mat1, mat2);
}
}
static int nthFibonacci(int n) {
if (n <= 1) return n;
// Initialize the transformation matrix
int[][] mat1 = {{1, 1}, {1, 0}};
matrixPower(mat1, n - 1);
// The result is in the top-left cell of the matrix
return mat1[0][0];
}
//Driver Code Starts
public static void main(String[] args) {
int n = 5;
int result = nthFibonacci(n);
System.out.println(result);
}
}
//Driver Code Ends
def multiply(mat1, mat2):
x = mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0]
y = mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1]
z = mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0]
w = mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1]
# Update matrix mat1 with the result
mat1[0][0], mat1[0][1] = x, y
mat1[1][0], mat1[1][1] = z, w
def matrixPower(mat1, n):
# Base case for recursion
if n == 0 or n == 1:
return
mat2 = [[1, 1], [1, 0]]
matrixPower(mat1, n // 2)
multiply(mat1, mat1)
# If n is odd, multiply by the helper matrix mat2
if n % 2 != 0:
multiply(mat1, mat2)
def nthFibonacci(n):
if n <= 1:
return n
# Initialize the transformation matrix
mat1 = [[1, 1], [1, 0]]
matrixPower(mat1, n - 1)
# The result is in the top-left cell of the matrix
return mat1[0][0]
#Driver Code Starts
if __name__ == "__main__":
n = 5
result = nthFibonacci(n)
print(result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static void multiply(int[,] mat1, int[,] mat2) {
int x = mat1[0,0] * mat2[0,0] + mat1[0,1] * mat2[1,0];
int y = mat1[0,0] * mat2[0,1] + mat1[0,1] * mat2[1,1];
int z = mat1[1,0] * mat2[0,0] + mat1[1,1] * mat2[1,0];
int w = mat1[1,0] * mat2[0,1] + mat1[1,1] * mat2[1,1];
// Update matrix mat1 with the result
mat1[0,0] = x;
mat1[0,1] = y;
mat1[1,0] = z;
mat1[1,1] = w;
}
static void matrixPower(int[,] mat1, int n) {
// Base case for recursion
if (n == 0 || n == 1) return;
int[,] mat2 = { {1, 1}, {1, 0} };
matrixPower(mat1, n / 2);
multiply(mat1, mat1);
// If n is odd, multiply by the helper matrix mat2
if (n % 2 != 0) {
multiply(mat1, mat2);
}
}
static int nthFibonacci(int n) {
if (n <= 1) return n;
// Initialize the transformation matrix
int[,] mat1 = { {1, 1}, {1, 0} };
matrixPower(mat1, n - 1);
// The result is in the top-left cell of the matrix
return mat1[0,0];
}
//Driver Code Starts
public static void Main(string[] args) {
int n = 5;
int result = nthFibonacci(n);
Console.WriteLine(result);
}
}
//Driver Code Ends
function multiply(mat1, mat2) {
const x = mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0];
const y = mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1];
const z = mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0];
const w = mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1];
// Update matrix mat1 with the result
mat1[0][0] = x;
mat1[0][1] = y;
mat1[1][0] = z;
mat1[1][1] = w;
}
function matrixPower(mat1, n) {
// Base case for recursion
if (n === 0 || n === 1) return;
const mat2 = [[1, 1], [1, 0]];
matrixPower(mat1, Math.floor(n / 2));
multiply(mat1, mat1);
// If n is odd, multiply by the helper matrix mat2
if (n % 2 !== 0) {
multiply(mat1, mat2);
}
}
function nthFibonacci(n) {
if (n <= 1) return n;
// Initialize the transformation matrix
const mat1 = [[1, 1], [1, 0]];
matrixPower(mat1, n - 1);
// The result is in the top-left cell of the matrix
return mat1[0][0];
}
//Driver Code Starts
// Driver code
const n = 5;
const result = nthFibonacci(n);
console.log(result);
//Driver Code Ends
Output
5
Time Complexity: O(log(n), We have used exponentiation by squaring, which reduces the number of matrix multiplications to O(log n), because with each recursive call, the power is halved.
Auxiliary Space: O(log n), due to the recursion stack.
[Other Approach] Using Golden ratio
The nth Fibonacci number can be found using theGolden Ratio, which is approximately =
\phi = \frac{1 + \sqrt{5}}{2} . The intuition behind this method is based on Binet's formula, which expresses the nth Fibonacci number directly in terms of the Golden Ratio.Binet's Formula: The nth Fibonacci number F(n) can be calculated using the formula:
F(n) = \frac{\phi^n - (1 - \phi)^n}{\sqrt{5}}
For more detail for this approach, please refer to this article.
Related Articles: