PHP算法:斐波那契數列的N種算法

2020-12-17 天隆網絡

前言

前段時間,遇到優化計算斐波那契數列的常規遞歸方法,但是一時間並沒有及時想到很好的方法,所以後面查找了相關資料,總結了多種計算解法,所以分享出來,和大家一起交流學習。

斐波那契數是什麼

斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為「兔子數列」,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波那契數列以如下被以遞推的方法定義:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)。

知道了斐波那契數,那麼下面我們就用多種不同的方法來計算獲取第N位斐波那契數。

普通遞歸

這種方法是最常規的,直接根據定義F(n)=F(n - 1)+F(n - 2)遞歸計算即可,但是性能是最低的。

/** * 普通遞歸 * @param int $n * @return int */function fib($n = 1){ // 低位處理 if ($n < 3) { return 1; } // 遞歸計算前兩位 return fib($n - 1) + fib($n - 2);}遞歸優化

從上面的遞歸方法可以看到,進行了很多的重複計算,性能極差,如果N越大,計算的次數太可怕了,那麼,既然因為重複計算影響了性能,那麼優化就從減少重複計算入手,即把之前計算的存儲起來,這樣就避免了過多的重複計算,優化了遞歸算法。

/** * 遞歸優化 * @param int $n * @param int $a * @param int $b * @return int */function fib_2($n = 1, $a = 1, $b = 1){ if ($n > 2) { // 存儲前一位,優化遞歸計算 return fib_2($n - 1, $a + $b, $a); } return $a;}記憶化自底向上

自底向上通過迭代計算斐波那契數的子問題並存儲已計算的值,通過已計算的值進行計算。使用for循環,減少遞歸帶來的重複計算問題。

/** * 記憶化自底向上 * @param int $n * @return int */function fib_3($n = 1){ $list = []; for ($i = 0; $i <= $n; $i++) { // 從低到高位數,依次存入數組中 if ($i < 2) { $list[] = $i; } else { $list[] = $list[$i - 1] + $list[$i - 2]; } } // 返回最後一個數,即第N個數 return $list[$n];}自底向上進行迭代

最低位初始化賦值,使用for從低位到高位迭代計算,從而得到第N個數。/** * 自底向上進行迭代 * @param int $n * @return int */function fib_4($n = 1){ // 低位處理 if ($n <= 0) { return 0; } if ($n < 3) { return 1; } $a = 0; $b = 1; // 循環計算 for ($i = 2; $i < $n; $i++) { $b = $a + $b; $a = $b - $a; } return $b;}公式法

通過了解斐波那契序列和黃金分割比之間的關係,使用黃金分割率計算第N個斐波那契數。

/** * 公式法 * @param int $n * @return int */function fib_5($n = 1){ // 黃金分割比 $radio = (1 + sqrt(5)) / 2; // 斐波那契序列和黃金分割比之間的關係計算 $num = intval(round(pow($radio, $n) / sqrt(5))); return $num;}無敵欠揍法

這個方法,我就不多說了吧,大家都懂的,但是千萬別輕易嘗試……

/** * 無敵欠揍法 * @param int $n * @return int */function fib_6($n = 1){ // 列舉了30個數 $list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269]; return $list[$n];}

相關焦點

  • LeetCode題解—斐波那契數列
    前言今天繼續算法題:斐波那契數列題目:斐波那契數列寫一個函數,輸入 n ,求斐波那契(Fibonacci)數列的第 n 項(即 F(N))。斐波那契數列的定義如下:F(0) = 0F(1) = 1 F(N) = F(N - 1) + F(N - 2)其中 N > 1.斐波那契數列由 0 和 1 開始,之後的斐波那契數就是由之前的兩數相加而得出
  • Fibonacci 斐波那契數列的幾種寫法、時間複雜度對比
    我看在家修煉編程技術是不錯的選擇,「用Python實現斐波那契數列」是我們在知識星球中每周給大家安排的一道題,你也可以先思考一下有哪些實現方法,說不定哪天面試就能派上用場,終有一日當上CTO贏取白富美從此走上人生巔峰。
  • 黃金分割比——斐波那契數列
    斐波那契數列(Fibonacci sequence),又稱黃金分割數列。
  • Python中斐波那契數列
    所以本節就講講如何用遞歸實現斐波那契數列。斐波那契數列的發明者,是義大利數學家列昂納多*斐波那契(Leomuado Fibonacci)。當年這個數列是由兔子交配的故事開始講起的:假如說兔子在出生兩個月後,就有了繁殖能力,此後這對兔子在接下來的每個月都能生出一對可愛的小兔子。假設所有兔子都不會老去,就這麼一直折騰下去,那麼一年以後可以繁殖多少對免子出來呢?
  • 斐波那契數列為什麼那麼重要,所有關於數學的書幾乎都會提到?
    下面我就盡我所能,講述一下斐波那契數列。一、起源和定義斐波那契數列最早被提出是印度數學家Gopala,他在研究箱子包裝物件長度恰好為1和2時的方法數時首先描述了這個數列。也就是這個問題:有n個臺階,你每次只能跨一階或兩階,上樓有幾種方法?
  • 送你一份Python算法的打怪升級路線圖 | 用 Python 實現各種常用算法
    主要包含數學上幾個基本問題,算術分析方法,斐波那契數列問題,以及最大公約數問題。知識點數學幾個基本問題算術分析方法斐波那契數列問題最大公約數問題數學上幾個基本問題在編程界,有這麼幾個經典的數學問題,這裡給大家簡單介紹下。
  • 如何掌握動態規划算法的套路?
    斐波那契數列斐波那契數列斐波那契數列是一個非常神奇的數列,它由義大利數學家萊昂納-斐波那契提出,其特徵是數列某一項的值是前兩項的和,也可以稱作黃金分割數列。萊昂納多·斐波那契我們可以用下面的通項公式來表示斐波那契數列。
  • 算法小專欄開篇:DFS之Fibonaci數列
    Fibonaci and DFS Implementation今天我還是從Fibonaci(斐波那契數列假設我要求第n項,我是不是要知道第n-1項和第n-2項,要求第n-1項,又要知道第n-2項和第n-3項,以此類推,就是一個不斷循環的過程,啥時候是個頭呢?我們知道第一項和第二項都是1,那當遞歸到這兩項時,直接返回1便可以了。就好像在一個迷宮,每一層有一個房間,每一層的房間裡有打開上一層需要的鑰匙,最上面一層的房間有奧利奧,怎麼吃到奧力給呢?
  • R語言中repeat循環的使用方法之素數和斐波那契數列前n項
    <- j + 1}if( j >= n) #如果j>=n說明n是素數print(n)n <- n + 1}這裡使用了兩個repeat循環。素數輸出結果例子4:求Fibonacci數列前N項在本號前面的文章中,曾使用for循環,while循環實現了求斐波那契數列前n項的方法,這裡再使用
  • 如何掌握動態規划算法的套路? - 51CTO.COM
    斐波那契數列斐波那契數列斐波那契數列是一個非常神奇的數列,它由義大利數學家萊昂納-斐波那契提出,其特徵是數列某一項的值是前兩項的和,也可以稱作黃金分割數列。萊昂納多·斐波那契我們可以用下面的通項公式來表示斐波那契數列。
  • 斐波那契數列的四種實現
    ……斐波那契有四樣寫法,你知道麼?」我愈不耐煩了,努著嘴走遠。孔乙己剛在命令行打開 Vim,想在裡面寫代碼,見我毫不熱心,便又嘆一口氣,顯出極惋惜的樣子。(改編自 魯迅《孔乙己》)在家閒著也是閒著,不如我們來看看,如何寫一個輸出斐波那契數列的代碼吧。先說下,什麼是斐波那契數列?
  • 七大查找算法
    查找算法分類:  1)靜態查找和動態查找;    註:靜態或者動態都是針對查找表而言的。動態表指查找表中有刪除和插入操作的表。  2)無序查找和有序查找。    無序查找:被查找數列有序無序均可;    有序查找:被查找數列必須為有序數列。
  • 斐波那契數列的兩個令人著迷的特性 - 電子通信和數學
    斐波那契數列是一個眾所周知的且經過研究的數字序列,經常在學校和休閒數學中使用,因為它很容易被那些受過有限的專業數學教育的人理解。序列的定義如下:第一項是零,第二項是一,任何其他項都是序列前兩項的和。這個序列的正式寫法如下當n> 1時。
  • 藍橋杯簡單java遞歸算法
    首先先簡介下遞歸算法:遞歸算法(英語:recursion algorithm)在計算機科學中是指一種通過重複將問題分解為同類的子問題而解決問題的方法。遞歸式方法可以被用於解決很多的計算機科學問題,因此它是計算機科學中十分重要的一個概念。
  • 小學生也可以寫出的,複雜數列-斐波那契數列
    有一個數列與黃金分割比就有著不可名狀的關係,而且它的特性非常的多,關鍵這個數列還非常簡單,小學生都可以寫出來。今天我們就來著重講一下這個數列,斐波那契數列的4個特性。1. 數列前兩項之和等於第三項如果設F(n)為該數列的第n項(n∈N*),那麼這句話可以寫成如下形式::F(n)=F(n-1)+F(n-2)以上就是斐波那契數列的官方定義。
  • 40.細說遞歸之二:Python求解斐波那契數列
    程序如下,稍微注意一下在循環裡3個變量的使用,如果不是特別清楚的話,可以回顧一下《10.裴蜀定理和歐幾裡得算法快速求解倒水問題》,裡面有介紹。那麼對於問題 f(n),該青蛙跳上n級臺階總共有多少種跳法,是否也能能轉化為規模更小的子問題來解決呢?我們換個思路,假設組隊玩王者,使用的決勝策略是等著英雄最後放一把必殺技。假設有 x 種玩法等著關羽放必殺技獲勝,有y種玩法等著諸葛亮放必殺技獲勝,請問一共有多種獲勝的玩法。很顯然是 x+y對於問題f(n)也一樣,不管前面怎麼跳。
  • 一篇文章了解Java基礎算法,排序、遞歸和折半查找,看完受益匪淺
    1.2 冒泡排序冒泡排序的算法整個數列分成兩部分:前面是無序數列,後面是有序數列初始狀態下,整個數列都是無序的,有序數列是空如果一個數列有n個元素,則至多需要n-1趟循環才能保證數列有序每一趟循環可以讓無序數列中最大數排到最後,(也就是說有序數列的元素個數增加1)每一趟循環都從數列的第一個元素開始進行比較,依次比較相鄰的兩個元素,比較到無序數列的末尾即可(而不是數列的末尾
  • 神奇的斐波那契數列
    我們用an表示一個數列的第n項,那麼斐波那契數列的規律「第一項和第二項是1,前兩項之和等於後一項」就可以表示成:兔子數列有什麼用?可能許多讀者覺得,斐波那契數列不過是浩如煙海的數學海洋中的一滴水而已。可是,從這個數列被提出的那一天起,到現在有800年了,人們對它的興趣一直有增無減,在許許多多的領域都發現了它的影子。在數學上有許多求「方法數」的問題,答案經常是斐波那契數列。
  • php幾種常用的加密解密算法
    內容原創本文給大家介紹php的三種常用的加密解密算法,有一定的參考價值,有需要的朋友可以參考一下,希望對你們有所幫助。php 自帶的加密函數:不可逆的加密函數為:md5()、sha1()、crypt()md5() 用來計算 MD5 哈稀md5(string$str[,bool$raw_output=FALSE] ) :string使用:$str = '123456789
  • Python實現斐波那契數列的幾種方法
    斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為「兔子數列」,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞推的方法定義