-2

Trying really hard to figure out how to solve this problem. The problem being finding nth number of Fibonacci with O(n) complexity using javascript.

I found a lot of great articles how to solve this using C++ or Python, but every time I try to implement the same logic I end up in a Maximum call stack size exceeded.

Example code in Python

MAX = 1000

# Create an array for memoization
f = [0] * MAX

# Returns n'th fuibonacci number using table f[]
def fib(n) :
        # Base cases
        if (n == 0) :
                return 0
        if (n == 1 or n == 2) :
                f[n] = 1
                return (f[n])

        # If fib(n) is already computed
        if (f[n]) :
                return f[n]

        if( n & 1) :
                k = (n + 1) // 2
        else : 
                k = n // 2

        # Applyting above formula [Note value n&1 is 1
        # if n is odd, else 0.
        if((n & 1) ) :
                f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
        else :
                f[n] = (2*fib(k-1) + fib(k))*fib(k)

        return f[n]


// # Driver code
// n = 9
// print(fib(n))

Then trying to port this to Javascript

const MAX = 1000;
let f = Array(MAX).fill(0);
let k;

const fib = (n) => {

    if (n == 0) {
        return 0;
    }

    if (n == 1 || n == 2) {
        f[n] = 1;

        return f[n]
    }

    if (f[n]) {
        return f[n]
    }

    if (n & 1) {
        k = Math.floor(((n + 1) / 2))
    } else {
        k = Math.floor(n / 2)
    }

    if ((n & 1)) {
        f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
    } else {
        f[n] = (2*fib(k-1) + fib(k))*fib(k)
    }

    return f[n]
}

console.log(fib(9))

That obviously doesn't work. In Javascript this ends up in an infinite loops. So how would you solve this using Javascript?

Thanks in advance

iremlopsum
  • 187
  • 3
  • 13

7 Answers7

3

you can iterate from bottom to top (like tail recursion):

var fib_tail = function(n){
        if(n == 0)
             return 0;
        if(n == 1 || n == 2)
             return 1;
        var prev_1 = 1, prev_2 = 1, current; 
        // O(n)
        for(var i = 3; i <= n; i++)
        {
            current = prev_1 + prev_2;
            prev_1 = prev_2;
            prev_2 = current;
        }
        return current;
 }
 console.log(fib_tail(1000))
OmG
  • 18,337
  • 10
  • 57
  • 90
1

The problem is related to scope of the k variable. It must be inside of the function:

const fib = (n) => {
    let k;

You can find far more good implementations here list

DEMO

Engineer
  • 47,849
  • 12
  • 88
  • 91
1

fibonacci number in O(n) time and O(1) space complexity:

function fib(n) {
    let prev = 0, next =1;
    if(n < 0)
        throw 'not a valid value';
    if(n === prev || n === next)
        return n;
    while(n >= 2) {
        [prev, next] = [next, prev+next];
        n--;
    }
    return next;
}
Alok Deshwal
  • 1,128
  • 9
  • 20
0

Just use two variables and a loop that counts down the number provided.

function fib(n){
    let [a, b] = [0, 1];
    while (--n > 0) {
      [a, b] = [b, a+b];
    }
    return b;
}

console.log(fib(10));
0

Here's a simpler way to go about it, using either iterative or recursive methods:

function FibSmartRecursive(n, a = 0, b = 1) {
    return n > 1 ? FibSmartRecursive(n-1, b, a+b) : a;
}

function FibIterative(n) {
    if (n < 2) 
        return n;

    var a = 0, b = 1, c = 1;

    while (--n > 1) {
        a = b;
        b = c;
        c = a + b;
    }

    return c;
}

function FibMemoization(n, seenIt = {}) {//could use [] as well here
    if (n < 2) 
        return n;
    if (seenIt[n]) 
        return seenIt[n];

    return seenIt[n] = FibMemoization(n-1, seenIt) + FibMemoization(n-2, seenIt); 
}

console.log(FibMemoization(25)); //75025
console.log(FibIterative(25)); //75025
console.log(FibSmartRecursive(25)); //75025
WesleyAC
  • 523
  • 6
  • 11
0

You can solve this problem without recursion using loops, runtime O(n):

function nthFibo(n) {
    // Return the n-th number in the Fibonacci Sequence
    const fibSeq = [0, 1]
    if (n < 3) return seq[n - 1]
    let i = 1
    while (i < n - 1) {
        seq.push(seq[i - 1] + seq[i])
        i += 1
    }
    return seq.slice(-1)[0]
}
PhiAgent
  • 158
  • 6
0

// Using Recursion
const fib = (n) => {
  if (n <= 2) return 1;
  return fib(n - 1) + fib(n - 2);
}

console.log(fib(4)) // 3
console.log(fib(10)) // 55
console.log(fib(28)) // 317811
console.log(fib(35)) // 9227465
dota2pro
  • 7,220
  • 7
  • 44
  • 79