斐波那契數列新解

斐波那契數列大家都很熟悉了

f(n) = f(n-1) + f(n-2)

f(0) = 1

f(1) = 1

如果要用計算機程序來實現這個功能的話,根據上面的遞推公式很容易想到使用遞歸的方式,使用遞推的優點是程序員不用考慮具體的計算過程,只要找好遞推的明確出口就可以了。

int fib(int n)
{
    if (n == 0 || n == 1) {
        return 1;
    }

    return fib(n - 1) + fib(n - 2);
}

遞歸的缺點是涉及到函數調用的開銷,執行的效率比較低。

當然也可以使用迭代的方式進行求解,迭代從已知的問題的解出發不斷的去推導出未知問題的解,說簡單點,遞歸是一個自頂向下的過程,迭代是自底向上的過程。

int fib(int n)
{
    int temp1 = 1;
    int temp2 = 1;
    
    for (int i = 2; i < n; i++) {
        int temp = temp1 + temp2;
        temp1 = temp2;
        temp2 = temp;
    }
    
    return temp1 + temp2;
}

迭代的方法沒有自身調用的過程,因此效率要比遞歸高很多;、

我們再回頭看下遞歸的實現,如果要求解fib(5)就需要得到fib(4)和fib(3),求解fib(4)就需要得到fib(3)和fib(2),求解fib(3)就需要得到fib(2)和fib(1),求解fib(2)就需要得到fib(1)和fib(0)。同樣求解fib(3)也要經過這樣的過程,勢必會造成重複計算和重複的函數入棧和出棧。如果我們在計算過程中將已經求解出來的結果保存下來,然後在計算中直接使用這些結果,這樣會效率高很多。這個方法就是動態規劃。

int fib(int n, int *table)
{
    if (table[n]) {
        return table[n];
    }

    table[n] = fib(n - 1) + fib(n - 2);

    return table[n];
}

int get_value(int n)
{
    int *table = (int *)malloc(sizeof(int) * (n + 1));
    table[0] = 1;
    table[1] = 1;

    return fib(n, table);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章