【演算法】Fibonacci解法總結
我這裡說的Fibonacci數列不僅僅是f(n-1) + f(n-2)的情況,也可以是f(n-1) + f(n-2) + … + f(n-k)的情況。但是這裡我們用f(n-1) + f(n-2)來進行討論,簡化理解,舉一反三。
解法一,遞迴
實現非常簡單。
int fibonacci(int i){
if(i==0){
return 0;
}else if(i==1){
return 1;
}else {
return fibonacci(i-1)+fibonacci(i-2);
}
}
}
解法二,動態規劃
核心程式碼如下:
long array[]=new long [n+1];
array[0]=0;
array[1]=1;
for(int i=2;i<n+1;i++){
array[i]=array[i-1]+array[i-2];
}
這種解法與遞迴解法相比,具有非常大的效能提升。
解法三,動歸優化
將空間優化到O(1):
int fib(int n) {
int last, nextToLast, answer = 0;
if (n <= 1) {
return 1;
}
last = nextToLast = 1;
for (int i = 0; i < n; i++) {
//f(n)=f(n-1)+f(n-2)
answer = last + nextToLast;
//f(n-2)=f(n-1)
nextToLast = last;
//f(n-1)=f(n)
last = answer;
}
return answer;
}
解法四,特殊解法
這種解法可以將時間複雜度優化到O(logn),牛客網的左老師書上講的非常清楚,這裡直接藉助過來以供參考:
/*
下面介紹一種時間複雜度是O(logn)的方法:
對於斐波那契數列1,1,2,3,5,8,13…….有如下定義:
F( n ) = F( n-1 ) + F( n-2 )
F( 1 ) = 1
F( 2 ) = 1
矩陣形式:
[ F( n+1 ) , F( n ) ] = [ F( n ) , F( n-1 ) ] * Q 其中 [ F( n+1 ) , F( n ) ]為行向量,Q = { [ 1, 1 ]; [ 1, 0 ] }為矩陣
則 [ F( n+1 ) , F( n ) ]=[ 1 , 0 ] * Qn ,
*/
struct Matrix
{
long long m_00, m_01, m_10, m_11;
Matrix ( long long m00 = 0, long long m01 = 0, long long m10 = 0, long long m11 = 0 )
:m_00( m00 ), m_01( m01 ), m_10( m10 ), m_11( m11 )
{
}
};
Matrix MatrixMultiply ( const Matrix & m1, const Matrix & m2 )
{
long long m00 = m1.m_00 * m2.m_00 + m1.m_01 * m2.m_10;
long long m01 = m1.m_00 * m2.m_01 + m1.m_01 * m2.m_11;
long long m10 = m1.m_10 * m2.m_00 + m1.m_11 * m2.m_10
long long m11 = m1.m_10 * m2.m_01 + m1.m_11 * m2.m_11;
return Matrix ( m00, m01, m10, m11 );
}
Matrix MatrixPower( unsigned int n )
{
assert(n > 0);
Matrix m;
if( n == 1)
{
m = Matrix(1, 1, 1, 0);
}
else if(n % 2 == 0)
{
m = MatrixPower( n / 2 );
m = MatrixMultiply( matrix, matrix );
}
else if( n % 2 == 1 )
{
m = MatrixPower( (n - 1) / 2 );
m = MatrixMultiply( m, m );
m = MatrixMultiply( m, Matrix( 1, 1, 1, 0 ) );
}
return m;
}
long long Fibonacci( unsigned int n )
{
int result[2] = { 0, 1 };
if( n < 2 )
return result[ n ];
Matrix Q = MatrixPower( n - 1 ); //注意:按定義式應該用[ 1, 0 ]*Q, 或者等價於{ [ 1 , 0 ]; [ 0, 0 ] }*Q, 但是因為顯然結果相同,所以略去這一步。
return Q.m_00;
}
總結
我覺得Fibonacci數列對於理解動態規劃也是非常重要,動態規劃的本質就是在遞迴中優化而來的。
Fibonacci問題還可以用來解上臺階問題,硬幣面值組合問題。
相關推薦
【演算法】Fibonacci解法總結
我這裡說的Fibonacci數列不僅僅是f(n-1) + f(n-2)的情況,也可以是f(n-1) + f(n-2) + … + f(n-k)的情況。但是這裡我們用f(n-1) + f(n-2)來進行討論,簡化理解,舉一反三。 解法一,遞迴 實現非常簡單
12、【演算法】查詢演算法總結
一、順序查詢 1、定義 順序查詢屬於無序查詢,從資料結構的一端開始,順序掃描,依次將掃描到的節點關鍵字與給定值K相比,若相等,則表示查詢成功,若掃描結束,仍未找到關鍵字與給定值K相等,則表示查詢失敗。 時間複雜度分析 查詢成功時:平均查詢長度為(N+1)/2
11、【演算法】排序演算法總結
常見排序演算法總結 一、氣泡排序 1、定義 氣泡排序是一種比較簡單的排序演算法,它會遍歷若干次要排序的數列,每次便利時,它都會從前往後依次的比較兩個相鄰的數的大小;如果前者比後者大,則交換它們的位置。 這樣一次遍歷之後,最大的元素就在數列的末尾了。採用相同的方法在
【演算法】最大的Fibonacci數
最大的Fibonacci數 無窮數列1,1,2,3,5,8,13,21,34,55…稱為Fibonacci數列,它可以遞迴地定義為 F(n)=1 ………..(n=1或n=2) F(n)=F(n-1)+F(n-2)…..(n>2) 現要你來求第n個斐波納奇數。(
【演算法】演算法知識點總結
## 專案知識點評估:1、fm + ffm + lr # fm 相比 lr 引進了特徵組合(二次項) # fm 解決了資料稀疏性導致的引數訓練不充分問題(尤其對於one-hot編碼之後) # ffm 增加了field,隱向量不僅與特徵相關,也與field相關
【演算法】最大似然估計總結筆記
最大似然估計學習總結------MadTurtle 1. 作用 在已知試驗結果(即是樣本)的情況下,用來估計滿足這些樣本分佈的引數,把可能性最大的那個引數作為真實的引數估計。 2. 離散型 設為離散型隨機變數,為多維引數向量,如果隨機變數相互獨立且概率計算式為P{,則可得概率函式為P{}=,在固定時,上式
【演算法】最近點對問題(暴力破解法)
簡單的畫了一張圖: 通過暴力方式,進行一次比較獲取兩個點之間的最短距離: //點對最近問題(暴力破解法) #include<iostream> #include<cmath> using namespace std; doub
【資料結構與演算法】揹包問題總結梳理
# 揹包問題總結分析 揹包問題是個很經典的動態規劃問題,本部落格對揹包問題及其常見變種的解法和思路進行總結分析 ## 01揹包 #### 問題介紹 有 N 件物品和一個容量是 V 的揹包。每件物品只能使用一次。 第 i 件物品的體積是 v[i],價值是 w[i]。 求解將哪些物品裝入揹包,
【Java】日誌知識總結和經常使用組合配置(commons-logging,log4j,slf4j,logback)
ng- binder mono leading black auto erb param 1.2 Log4j Apache的一個開放源碼項目,通過使用Log4j,我們能夠控制日誌信息輸送的目的地是控制臺、文件、GUI組件、甚至是套接口服務 器
【雜文】2017年度總結
導讀 付出 結束 分享圖片 轉折 tps 天都 新人 自己 導讀 在2017年的尾巴,回顧過去一整年,有些成長收獲,有些失落惆悵;好的壞的,經歷過的,都需要重溫,算是對2017年的正式告別。 回顧 過去看現在 在2016年度總結中,有對2017年的展望。 技術書籍的
【評分】Beta 答辯總結
mage www. www nan -s 好的 ext html 6.5 【評分】Beta 答辯總結 總結 按時交 - 有分 晚交 - 0分 遲交一周以上 - 倒扣本次作業分數 抄襲 - 倒扣本次作業分數 由於前期不夠重視,到beta評分才發現有5組的代碼提交僅由
【轉】PHP面試總結
tar htm itl body .cn clas tps html ref 文章出處:https://www.cnblogs.com/codetao/p/6418127.html【轉】PHP面試總結
【轉載】CPU相關總結
case total 總結 touch ads socket RM Oday side What is the difference between Processor, Core, Logical Processor ? Processor : It’s the ph
【MySQL】簡單命令總結
MySQL查看數據庫 SHOW DATABASES; 創建數據庫 CREATE DATABASE IF NOT EXISTS 數據庫名; 選擇數據庫 USE 數據庫名; 查看數據庫中的數據表 SHOW TABLES; 刪除數據庫 DROP DATABASE IF EXISTS 數據庫名; 創建一個簡單的數據庫
【HDU1848】Fibonacci again and again(博弈論)
spa sync splay turn pro [1] 斐波那契 play cci 【HDU1848】Fibonacci again and again(博弈論) 題面 Hdu 你有三堆石子,每堆石子的個數是\(n,m,p\),你每次可以從一堆石子中取走斐波那契數列中一個元
【POJ3070】Fibonacci
題意 求Fibn mod m的值 m=10000,0<=0<=2*109 分析 矩陣快速冪模板 設f(n)={Fibn,Fibn+1},可得到單位矩陣為{(0,1)(1,1) } 程式碼 #include<iostream> #include<cstdio&
【演算法】字串迴圈移位後是否包含
問題 給定兩個字串s1和s2,要求判斷s2是否能夠被通過s1做迴圈移位(rotate)得到的字串包含。 例如,s1=AABCD和s2=CDAA,返回true;給定s1=ABCD和s2=ACBD,返回false。 解法一 最直接最笨的方法就對s1進行迴圈移動,再
13、【演算法】演算法複雜度分析
一、演算法的時間複雜度分析 1、時間複雜度的定義 在進行演算法分析時,演算法中基本操作語句重複執行的次數是問題規模n的某個函式,用T(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函式,
【演算法】第三章作業 實踐報告
【演算法】實踐第三章作業 1. 實踐題目 最大子段和 2. 問題描述 給定n個整數(可能為負數)組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。當所給的整數均為負數時,定義子段和為0。
【演算法】-003 三次貝塞爾曲線的交點
【演算法】-003 三次貝塞爾曲線的交點 最近在工作中遇到一個問題,想通過計算兩條三次貝塞爾曲線的交點位置。嘗試了列舉法之後覺得計算速度太慢,於是來找其他演算法。 文章目錄 【演算法】-003 三次貝塞爾曲線的交點 1、 列舉法求貝塞爾曲線交