劍指offer-面試題9:斐波那契數列
阿新 • • 發佈:2019-02-05
題目一:寫一個函式,輸入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);
}
實用解法:遞迴解法種包含著許多重複計算,如果我們從下往上計算,則可以避免重複的計算。
矩陣解法:利用數學公式,轉換為求指數問題,而求指數又可以進一步簡化計算,時間複雜度O(longn).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; }
題目二:一隻青蛙一次可以跳上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)。#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; }