大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項為0)。
n<=39
1、最常見的遞迴演算法,複雜度太高o(k^n)
//遞迴 --會做大量冗餘計算
class solution else if(n==1) else }};
2、利用陣列存放之前的計算結果,時間負責度為o(n),空間複雜度也為o(n)
//陣列存放--浪費空間
class solution else
return a[n];
} }};
3、動態規劃。其實就是說,對於這個斐波那契數列來講,只需要考慮當前值和之前的2個值即可。每次迴圈都可以進行一次狀態轉移。時間複雜度為o(n),空間複雜度為o(k)
//動態規劃--狀態轉移
//只關心所求值與所求相鄰的兩個數
class solution
return now;}};
//動態規劃簡化版
class solution
return last;}};
4、使用矩陣,複雜度會降到o(logn)
/* o(logn)解法:由f(n) = f(n-1) + f(n-2),可以知道
* [f(n),f(n-1)] = [f(n-1),f(n-2)] *
* 所以最後化簡為:[f(n),f(n-1)] = [1,1] * ^(n-2)
* 所以這裡的核心是:
* 1.矩陣的乘法
* 2.矩陣快速冪(因為如果不用快速冪的演算法,時間複雜度也只能達到o(n))
*/public static int fibonacci4(int n)
if (n == 1 || n == 2)
int base = ,
};//求底為base矩陣的n-2次冪
int res = matrixpower(base, n - 2);
//根據[f(n),f(n-1)] = [1,1] * ^(n-2),f(n)就是
//1*res[0][0] + 1*res[1][0]
return res[0][0] + res[1][0];
}//矩陣乘法
public static int multimatrix(int m1,int m2) }}
return res;}/*
* 矩陣的快速冪:
* 1.假如不是矩陣,叫你求m^n,如何做到o(logn)?答案就是整數的快速冪:
* 假如不會溢位,如10^75,把75用用二進位制表示:1001011,那麼對應的就是:
* 10^75 = 10^64*10^8*10^2*10
* 2.把整數換成矩陣,是一樣的
*/public static int matrixpower(int m, int p) //單位矩陣乘任意矩陣都為原來的矩陣
//用來儲存每次的平方
int tmp = m;
//p每迴圈一次右移一位
for ( ; p != 0; p >>= 1)
//每次儲存一下平方的結果
tmp = multimatrix(tmp, tmp);
}return res;
} 5、利用生成函式,時間複雜度會變成o(1)
public static int fibonacci(int n){
double root=math.sqrt(5);
return (int)math.round(math.pow(((1 + root)/2), n) / root - math.pow(((1 - root)/2), n) / root);
之所以用math.round(),是因為double都會有那麼一丁點的誤差,所以需要使用四捨五入來補上這點殘差。它其實是遞推公式的解:
**部落格:
劍指offer 斐波那契數列
題目1描述 寫乙個函式,輸入n,求斐波那契數列的第n項。斐波那契數列的定義如下 f n 0 n 0 f n 1 n 1 f n f n 1 f n 2 n 1 分析描述 在大多數的c語言教科書中,一般會用遞迴求斐波那契數列。如下 long long fibonacci unsigned int n ...
劍指offer 斐波那契數列
記錄來自 劍指offer 的演算法題。題目如下 寫乙個函式,輸入n,實現斐波那契數列的第n項。斐波那契數列的定義如下 f n 01 f n 1 f n 2 n 0 n 1n 1 教科書上通常在介紹遞迴的時候都會使用斐波那契數列作為例子,然後給出下列解法 long long fibonacci uns...
劍指offer 斐波那契數列
現在要求輸入乙個整數n,請你輸出斐波那契 fibonacci 數列的第n項。此題易用遞迴來實現 public intfibonacci int n 但是上述的遞迴解法有很嚴重的效率問題。以求解 f 10 為例,想求得 f 10 需要先求得 f 9 和 f 8 同樣,想求得 f 9 需要先求得 f 8...