最近看到斐波那契數列的算法,以爲挺簡單的,因而深刻研究了一下,發現算法其實還挺美妙的。
正常的fibonacci
通常是這麼算的:算法
function fibonacci(n) { if (n === 1 || n === 2) { return 1; } return fibonacci(n - 1) + fibonacci(n - 2); }
可是我在測試的時候發現,當n數值比較小的時候,這個函數性能還能夠,運行時間也不慢,可是當n取30,40,60的時候,我電腦的CPU就淡定不了,這事我發現,它們所消耗的時間以下:數組
當計算到60的時候,耗費的時間爲87.049s,不只時間太長,並且增長了CPU的壓力,感受這個算法性能不是很好。這個算法的缺點就是會重複計算許屢次相同的f(n),好比要計算f(5),將會計算兩次f(3),一次f(4),要是n取值更大的話,這些數值將會重複計算屢次,因而想減小重複計算。函數
該方法的思路是定義一個長度爲n的數組,n的每一項初始值爲-1,當計算出每個f(n)
的值時保存爲a[n]
,這樣下一次計算f(n)
的時候,先從數組a中查看是否存在a[n]===-1
,若arr[n] ===-1
,則計算f(n)
,反之,則取a[n]
的值。代碼以下:性能
function fibonacci1(n) { var vArray = new Array(n+1); for(var index = 0;index <=n;index++){ vArray[index] = -1; } return calcFn(n,vArray) } function calcFn(n,arr) { if (n === 1 || n === 2) { return 1; } if(arr[n] ===-1){ // console.log(n) arr[n] = calcFn((n - 1),arr) + calcFn((n - 2),arr) } return arr[n] }
計算結果:如下分別是n爲30,40,60的計算結果測試
從上圖來看,相對於第一種通用的方式,這個方法計算較大數值時,耗時明顯縮短了,大大提升了運算速度。優化
該方法的思路是,根據此通項的計算原理,a[n]=a[n-1]+a[n-2]
,咱們只須要保留a[n]
的前兩項,由f(1)=f(2)=1
可知,咱們可初始化一個長度爲2的數組a=[1,1]
,則f(3)=a[0]+a[1]=3
,而後可將交換移動數組的的兩項,好比計算完f(3)
以後,a=[1,3]
,此時的數組a表明a[0] = f(2),a[1]=f(3)
,若我要計算f(4)
,則f(4)=a[0]+a[1]
,以此類推。代碼以下:spa
function fibonacci2(n) { var arr = [1, 1]; for(let i = 3; i <= n; ++i) { let temp = arr[1] arr[1] += arr[0] arr[0] = temp } return arr[1] }
實驗結果代表,此方法優化以後,計算耗時跟優化方法一差很少code
兩種優化的方法都能縮短計算耗時,均可以免同一數值屢次計算,二者的差別:blog