1

Here is my implementation of the fibonacci sequence using java

/**
 * Returns nth fibonacci number
 */
public class fib {

   public static void main(String[] args){
      System.out.println(fibonacci(12));
   }

   public static int fibonacci(int n) {
      if (n == 0){
         return 0;
      } else if (n == 1){
         return 1;
      } else {
         return fibonacci(n - 1) + fibonacci(n - 2);
      }
   }
}

But visualization of this method using recursion made me think it would be a lot faster. Here is a visualization of fib(5). https://i.stack.imgur.com/jxkdf.jpg But this got my thinking, notice at the bottom when we bubble up from the bottom of the recursive path we calculate fib(2), fib(3) and fib(4) but then we recalculate fib(3) on the very top right branch. So I was thinking when we are bubbling back up why not save fib(3) calculated from the left branch so we don't do any calculations on the right branch like my method currently does, like a hashtable while coming back up. My question is, how do I implement this idea?

3 Answers3

2

When you want to add the HashMap and stay with your original approach, try this:

static HashMap<Integer, Integer> values = new HashMap<Integer, Integer>();

public static void main(String[] args){
    values.put(0, 0);
    values.put(1, 1);
    System.out.println(fibonacci(12));
}

public static int fibonacci(int n) {
    if (values.containsKey(n)){
        return values.get(n);
    } else {
        int left = values.containsKey(n - 1) ? values.get(n - 1) : fibonacci(n - 1);
        values.put(n - 1, left);
        int right = values.containsKey(n - 2) ? values.get(n - 2) : fibonacci(n - 2);
        values.put(n - 2, right);
        return left + right;
    }
}

This approach could be very fast if you call it more often because the fibonacci results are already stored in the values (for sure this could also be done with other approaches):

public static void main(String[] args){
    values.put(0, 0);
    values.put(1, 1);
    System.out.println(fibonacci(12));
    System.out.println(fibonacci(11));
    System.out.println(fibonacci(10));
}
wake-0
  • 3,918
  • 5
  • 28
  • 45
1

For a fast calculation, you do not need recursion at all - just shift the intermediate results

public static int fibonacci(int n) {
  if (n == 0) {
  return 0;
  } else {
    int npp = 0; // pre-previous number
    int np = 1; // previouse number
    int r = 1; // current number, eventually the result
    for (int i = 2; i <= n; i++) {
      r = np + npp;
      npp = np;
      np = r;
    }

    return r;
  }
}
Fahad Siddiqui
  • 1,829
  • 1
  • 19
  • 41
Erich Kitzmueller
  • 36,381
  • 5
  • 80
  • 102
0

In order to avoid repeated calculations, you can use dynamic programming. BTW, this is not a memory optimized solution, but it can be faster than the recursive one.

public static int fibonacci(int n)
{    
    int f[] = new int[n+1];

    for (int i = 0; i <= n; i++) {
        if(i == 0 || i == 1) {
            f[i] = i;
        }
        else {
            f[i] = f[i-1] + f[i-2];
        }
    }

    return f[n];
}
Shahid
  • 2,288
  • 1
  • 14
  • 24