遞迴函式計算費波那契數的時間複雜度分析

遞迴函式計算費波那契數的時間複雜度分析
Photo by Ludde Lorentz / Unsplash

大家好,不知道大家今天有沒有吃飽呢?

剛入門程式設計,學到「遞迴」操作的時候,老師們都很喜歡舉「費波那契數」的計算為例。以下,我也用 JavaScript 程式碼展示一下費波那契數的計算:

function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(10)); // 55

這樣的遞迴函式看起來是沒有問題的,但是您可以把 45 以上的數字帶入這個函式試試看。執行的時候,您可能會以為程式卡住了,其實並沒有卡住,只是計算量會變得非常驚人!

function recursiveFibonacci(n) {
  if (n <= 1) return n;
  return recursiveFibonacci(n - 1) + recursiveFibonacci(n - 2);
}

function logFibonacciWithTime(n) {
  const label = `f(${n})`;
  console.time(label);
  const result = recursiveFibonacci(n);
  console.timeEnd(label);
  console.log(`${label} = ${result}`);
}

logFibonacciWithTime(35);
logFibonacciWithTime(40);
logFibonacciWithTime(41);
logFibonacciWithTime(42);
logFibonacciWithTime(43);
logFibonacciWithTime(44);
logFibonacciWithTime(45);
logFibonacciWithTime(46);
logFibonacciWithTime(47);
logFibonacciWithTime(48);
logFibonacciWithTime(49);
logFibonacciWithTime(50);
bun index.js

[55.70ms] f(35)
f(35) = 9227465
[386.84ms] f(40)
f(40) = 102334155
[631.33ms] f(41)
f(41) = 165580141
[1016.06ms] f(42)
f(42) = 267914296
[1.70s] f(43)
f(43) = 433494437
[2.72s] f(44)
f(44) = 701408733
[4.32s] f(45)
f(45) = 1134903170
[6.97s] f(46)
f(46) = 1836311903
[11.27s] f(47)
f(47) = 2971215073
[18.26s] f(48)
f(48) = 4807526976
[29.58s] f(49)
f(49) = 7778742049
[61.63s] f(50)
f(50) = 12586269025

我想像的結果是這些計算都可以在幾毫秒的時間搞定啊,為什麼跟我想的差了幾百上千倍呢?

我們試著分析看看它的時間複雜度:

假設 n 是一個大數,我們計算 fibonacci(n - 2) 的需要 t 單位的時間,並且假設計算 fibonacci(n - 1) 需要 a 倍的 t 單位時間 at。

那麼計算 fibonacci(n) 就是需要 at + t 的時間,而計算 fibonacci(n + 1) = fibonacci(n) + fibonacci(n — 1) 所需的時間就是 (at + t) + at 的時間。

計算 fibonacci(n + 1) 的時間比上計算 fibonacci(n) 的時間會等於計算 fibonacci(n) 的時間比上計算 fibonacci(n — 1) 的時間。所以:

[(at + t) + at] : (at + t) = (at + t) : at

=> (at + t)² = (2at + t) * at

移項之後可以得到 a²t² — at² — t² = 0

由於 t 是常數,我們可以把 t² 除掉,變成 a² — a — 1 = 0, a > 0。解方程式就可以得到 a = (1 + sqrt(5)) / 2 = 1.618034…. 這正好是黃金分割率 φ。

每當要計算的費波那契數增加 1 ,計算的時間就會增加 φ 倍,所以用遞迴的方法計算費波那契數的時間複雜度就是 O(φn)。計算時間呈現指數級別增長的算法是相當糟糕的。

沒有數據的話您可能感覺不出來,我的電腦執行以上的程式計算 fibonacci(50) 的時間是 62 秒左右,那麼如果要計算 fibonacci(100) 的話,理論上可能要花費的時間是 φ⁵⁰ * 62 秒。您可以按計算機算算看,大約是五萬至七萬「年」左右的時間呢,嚇人吧?

Read more

《逆思維》4 - 如何贏得辯論並影響他人?

《逆思維》4 - 如何贏得辯論並影響他人?

好久不見,這個網站已經好一陣子沒有更新一些東西了。 在寫這篇文的時候,我一直在思考一個問題:我是該憑著我讀完的印象來寫呢?還是我可以 open book 邊寫邊重新閱讀這本書,從作者的文字中尋找靈感呢?我想了一下覺得邊寫邊重新閱讀好像挺好的,可以幫助我補足第一次閱讀時沒有理解到、沒有掌握到的道理。 這章的主軸是一個 AI 與人類辯士之間的辯論賽,主題為政府是否該補助幼兒園。AI 為正方,人類為反方。AI 擅長理性地分析大量的資料,並且給出有利的證據來佐證自己的論點。有那麼齊全的資料,以及強大的計算能力,看起來 AI 是贏定了;然而辯論到後面,有許多評審、觀眾的想法反而被帶到人類辯士的這邊。是為什麼呢? 想要說服一個人、給人建議,數據與分析當然是必須的。但也要考量我們人類並不是完全理性的,舉再多的數據佐證,不會買單的人就是不會買單。有沒有什麼好方法可以說動一個人呢?作者研究了談判專家,和普通的談判者在談判中所使用到的技巧,發現談判專家們並沒有花特別大的篇幅提供證據、分析、數據那些東西。而是談判專家會找到雙方立場的共同點,並且以提問表達出好奇,引發雙方有更進一步的思考,對方心裡可能也

By Shiangogo
搶救網站大作戰!

搶救網站大作戰!

去年大約 12 月底,我用了 Zeabur 這個平台架設我的網站。因為有先人寫好了 Ghost 的 infra 模板,所以我架設起來非常方便快速。 原本是抱持著一個白嫖免費服務的心態使用 Zeabur 的,結果今天心血來潮想進網站看一看,才發現服務掛掉了。進到 Zeabur Dashboard 一看,發現已經頂到免費額度上限,服務被自動停用了!為了避免資料被自動刪除,話不多說,只好先課金 5 美金了! 課完金之後,我嘗試重啟主服務,似乎也遇到了問題,主服務一直崩潰重啟。這不曉得是 Zeabur 平台不夠完善,還是 Infra 的 Template 寫得有問題。我想,既然主服務有狀況,先確保 DB 資料安全應該比較實在。 還好 MySQL 服務是活著的,目前的策略是先用 Zeabur

By Shiangogo
《逆思維》3 - 想法有誤的喜悅

《逆思維》3 - 想法有誤的喜悅

承認自己的錯誤,並且拋棄成見,不再堅持「信念」,才能讓我們更接近真相。 在《逆思維》這本書的第三章,最令我印象深刻的例子,就是對於 2016 年美國總統大選前,共和黨內初選結果的預測。當時沒有人認為川普會贏得初選,甚至把川普當成是笑話。但是有一位預測專家尚皮耶・波岡斯認為川普高機率會贏。為什麼大家都預測錯,但是尚皮耶可以正確預測呢?大家都被「信念」蒙蔽了雙眼,沒辦法真的客觀、理性地探究事情的本質。 很多時候我們遇到的事情都有兩面性,或是多面性。但我們寧願只看其中的一面,並且死死抓著它,讓它成為一切推論的不可動搖的根基。這種信念有可能出現問題,與事實相去甚遠,但我們礙於面子、自尊心,沒辦法調整自己的看法,並承認自己的錯誤。 舉個近期的例子,就是去年 2025 年,在台灣由民進黨發起的大罷免行動。在罷免投票的前一兩週,罷團的聲勢相當浩大,每天搭車在捷運站外都會看到他們的宣傳。那時,就連反對罷免的我也認為國民黨和民眾黨完蛋了。然而罷免開票結果卻讓罷免支持者集體崩潰,完全沒有立委被罷免成功。在路邊、網路上,鋪天蓋地地宣傳大罷免,

By Shiangogo
手把手教你用 GitHub Pages 搭建網站!

手把手教你用 GitHub Pages 搭建網站!

我們公司內部的讀書分享會,有同事用AI vibe coding 把簡報做成網頁 HTML 的形式。我心想這也太酷了吧,我也來搞一個試試看!感謝好心的同事有留下那個簡報的原始碼,我也用 vibe coding 把那份簡報魔改成一個讀書會簡報編輯器,並且輸出了一份 HTML 簡報。 我覺得把簡報做成網頁的優點很明顯,不需要安裝任何簡報軟體,只要有瀏覽器,輸入 URL 就可以使用簡報,而且想玩什麼花樣,都可以用 CSS、JavaScript 去寫;但同樣的,缺點也很大——也就是把 HTML 做出來。把 HTML 做出來之後還會遇到問題,如果只是用瀏覽器打開這個 HTML,YouTube 的影片會沒辦法播放。 把簡報做成 HTML 的這個難點,我相信可以透過 AI 來解決。或是說簡報軟體也可以把做好的東西轉換成 HTML?這個我就沒有研究了,但我猜應該有類似功能。

By Shiangogo