代码改变世界

Dynamic Programming: Fibonacci

2019-03-31 14:06  imyang  阅读(351)  评论(0编辑  收藏  举报

Recently I watched an interesting video in youtube, the vbloger use calculating Fibonacci number to explain dynamic programming

after watch this video, I decide to write it down in English, also for practice my written English

ok, in this article, we will assume you already know what's Finabonacci number

commonly, we always use recursion to get the number, it's pretty easy to implement it

Recursion:

int Fib(int n)
{
    if (n <= 2) return 1;
    return Fib(n - 1) + Fib(n - 2);
}

This is also the example when we learn recursion

the time complexity is O(X=2^n), it's calcualted like this

Fib(n) once

Fib(n -1) once

Fib(n-2) twice

Fib(n-3) Third

the total time is equal = 1+2+3...+(n - 1) = 2^n

this approach works for most of cases, but it's no effective and will cause stack over exception if the number is big, because there's call stacks

it cost really long time when I set n = 100

so we need to improve the recursion

we can see some numbers are calculated multiple times

for instance, Fib(5) = Fib(4) + Fib(3), Fib(4) = Fib(3) + Fib(2), Fib(3) will be calculated twice

Let's think about an approach to avoid it

Recursion and Memoize

in this appraoch, we will store the number when it's calculated

int Fib(int n, int[] memoized)
{
    if (memoized[n] != 0) return memoized[n];
    if (n <= 2) return 1;
    int f = Fib(n - 1) + Fib(n - 2);
    memoized[n] = f;
    return f;
}

ok, we will only calculate once for one number, and the time complexity is O(n)

however there are still lots of call stack while calculating

the above 2 approaches are calculated from top to bottom, from n, n-1,...,1

How about calculate from bottom, just like the exmaple number see, 1,1,2,3,5,6...

Bottom Up

int Fib(int n)
{
    if (n <= 2) return 1;
    var memoized = new int[n + 1];
    memoized[1] = 1;
    memoized[2] = 1;
    for (int i = 3; i <= n; i++)
    {
        memoized[i] = memoized[i - 1] + memoized[i - 2];
    }
    return memoized[n];
}

in this approach, we calcuate from bottom to up, altthough we add extra space for new array, but there are not so many call stacks, it's effective

The time complexity is also O(n) 

 

ok, this is the summary of the video, I also found a video which explain dynamic programming by MIT

Please also find this video for reference

Dynamic Programming I: Fibonacci, Shortest Paths