Nth Fibonacci Number

Last Updated : 2 Apr, 2026

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.

Try It Yourself
redirect icon

[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
C++
//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
C
//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
Java
//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
Python
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
C#
//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
JavaScript
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.

introduction_to_recursion
C++
//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
C
//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
Java
//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
Python
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
C#
//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
JavaScript
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.
C++
//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
C
//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
Java
//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
Python
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
C#
//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
JavaScript
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.

C++
//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
C
//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
Java
//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
Python
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
C#
//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
JavaScript
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: \begin{pmatrix}1 & 1 \\1 & 0 \end{pmatrix}This matrix captures the Fibonacci relationship. If we multiply this matrix by itself multiple times, it can give us Fibonacci numbers.

To find the Nth Fibonacci number we need to multiply transformation matrix (n-1) times, the matrix equation for the Fibonacci sequence looks like:
\begin{pmatrix}1 & 1 \\1 & 0\end{pmatrix}^{n-1}=\begin{pmatrix}F(n) & F(n-1) \\F(n-1) & F(n-2)\end{pmatrix}

After raising the transformation matrix to the power n - 1, the top-left element F(n) will give the nth Fibonacci number.

C++
//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
C
//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
Java
//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
Python
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
C#
//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
JavaScript
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:

Comment