最近看到斐波那契数列的算法,以为挺简单的,因而深刻研究了一下,发现算法其实还挺美妙的。
正常的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