1. 程式人生 > >【劍指offer】面試題9:斐波那契數列

【劍指offer】面試題9:斐波那契數列

題目

寫一個函式,輸入n, 求斐波那契數列的第n項。

遞迴

問題規模為:
T(n)=T(n1)+T(n2)
如果我們估計一下,讓 T(n1)=T(n2)
那麼T(n)=2T(n1)
那麼O(n)=2n

簡介而不高效

long long Fibonacci(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;
    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

遞推

一次遍歷,複雜度為O(n)
個人覺得是最優,省空間,省時間

long
long Fibonacci(int n) { if (n <= 0) return 0; if (n == 1) return 1; long long n2 = 0; long long n1 = 1; long long n0; for (int i = 2; i <= n; i ++) { n0 = n2 + n1; n2 = n1; n1 = n0; } return n0; }

矩陣乘法

原理就是:

[f(n)f(n1)f(n1)f(n2)]=[11
10
]
n1

如果加上快速冪的話,複雜度可以變為O(logn)

所以下面的實現只寫函式:

Matrix FastPower(const Matrix & m, int n) {
    if (n == 1) {
        return m;
    }
    if (n % 2 == 0) {
        return FastPower(m, n/2) * FastPower(m, n/2);
    } else {
        return FastPower(m, (n - 1)/2) * FastPower(m, (n - 1)/2) * m;
    }
}

Matrix m = Matrix(2
, 2); //在此我們輸入 1,1,1,0 初始化這個矩陣 int Fibonacci(int n) { if (n <= 0) return 0; if (n == 1) return 1; Matrix m1 = m; m1 = FastPower(m1, n-1); return m1.get(0, 0); //為f(n) } int main() { for(int i = 0; i < 10; i ++) cout << Fibonacci(i) << endl; }

(資料型別這裡用int,如果要用大數的話,可以自己換資料型別)