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

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

題目一:寫一個函式,輸入n,求斐波那契(Fabonacci)數列的第n項。斐波那契數列的定義如下:


效率很低的解法:遞迴
long long Fibonacci(unsigned n)
{
    if(n <= 0)
        return 0;
    if(n == 1)
        return 1;
    return Fibonacci(n-1) + Fibonacci(n-2);
}
實用解法:遞迴解法種包含著許多重複計算,如果我們從下往上計算,則可以避免重複的計算。
long long Fibonacci(unsigned n)
{
    int result[2] = {0,1};
    if(n < 2)
        return result[n];

    long long fibNMinosOne = 1;
    long long fibNMinusTwo = 0;
    long long fibN = 0;
    for(unsigned int i = 2; i <= n; ++i)
    {
        fibN = fibNMinueOne + fibNMinueTwo;
        
        fibNMinusTwo = fibNMinusOne;
        finbNMinusOne = fibN;
    }
    return fibN;
}
矩陣解法:利用數學公式,轉換為求指數問題,而求指數又可以進一步簡化計算,時間複雜度O(longn).
#include <iostream>
using namespace std; 

long long martrix[4] = {1,1,1,0};

long long* multiply(long long* martrixA, long long* martrixB)
{
	if(martrixA == NULL || martrixB == NULL)
		cout << "Input is wrong" << endl;
	long long* martrixC = new long long[4];
	martrixC[0] = martrixA[0]*martrixB[0] + martrixA[1]*martrixB[2];
	martrixC[1] = martrixA[0]*martrixB[1] + martrixA[1]*martrixB[3];
	martrixC[2] = martrixA[2]*martrixB[0] + martrixA[3]*martrixB[2];
	martrixC[3] = martrixA[2]*martrixB[1] + martrixA[3]*martrixB[3];
	return martrixC;
}
long long* power(unsigned n)
{
	if(n == 0)
		return 0;
	if(n == 1)
		return martrix;
	if(n%2 == 0)
		return multiply(power(n/2), power(n/2));
	else
		return multiply(martrix,multiply(power((n-1)/2), power((n-1)/2)));
}
		
long long Fibonacci(unsigned n)
{
	if(n <= 2)
		return martrix[3-n];
	return *power(n-1);
}

int main() {
	// your code goes here
	cout << Fibonacci(10) << endl;
	getchar();
	return 0;
}
題目二:一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。 思路:這個問題書上說也是一個斐波那契數列問題,一開始沒想起來,看來還是缺少程式設計師思維。設跳上n級臺階的跳法為n的函式f(n),如果第一次跳1級,那麼還剩下n-1級需要跳,跳法即為f(n-1);如果第一次跳2級,那麼還剩下n-2級臺階,跳法為f(n-2),有f(n) = f(n-1)+f(n-2),果然又是個斐波那契數列問題! 問題擴充套件:如果青蛙每次跳的級數不侷限於1級和2級,也可以是n級,那麼跳上n級臺階有多少種跳法? 思路:如果在跳上n級臺階之前的一跳級數為1,那麼前面n-1級臺階的跳法為f(n-1),同理這一跳也可能是2,3,直到n,所以有f(n) = f(n-1) + f(n-2) + …+f(1) + 1,用數學歸納法可以證明f(n) = 2^(n-1)。