Fibonacci Numbers
2016-03-20 10:19
288 查看
阅读TAOCP中Fibonacci Numbers内容后的想法。
Fibonacci Numbers,形如以下的数列
0,1,1,2,3,5,8,13,21,34, … ,
在这个数列中从第三项开始,每一个元素都是前两个元素的和。
可以写成以下形式:
由此我们就可以得到递归代码:
int Fibonacci_Numbers(int n)
{
if(n==0)
return 0;
if(n==1)
return 1;
return Fibonacci_Numbers(n-1)+Fibonacci_Numbers(n-2);
}
对于上面的算法,经历的时间是指数级的
通过模拟上面的过程可以发现有许多状态是重复的。
我们可以改进上面的过程,改用递推的方式。将原来的状态保留下来,便于以后的使用。
经过此番改进我们可以得到时间复杂度为O(n)的算法。
但是我们通过另一个关于Fibonacci Numbers表达式可以得到另一个算法。
当我们该等式转化为矩阵的形式(此处还不太会数学符号的插入),我们得到一个求解Fibonacci Numbers的可能更有效的算法。
当我们改进成上面的程序时发现并不会比O(n)的算法更优。
如果将 n 表示成 n = b0*20 + b1*21 + b2*22 + ...+ bn*2n .
可以得到一些启示,将上面的程序写成这样子:
参考博文:http://blog.csdn.net/y990041769/article/details/22311889
http://blog.csdn.net/liuzhanchen1987/article/details/7712640
此处的时间复杂度应该是O(logn),所用算法思想类似快速幂取模。
此外在书中还有一些有趣的式子。
1 ) Fn+m = Fn*Fn+1 + Fm-1*Fn.
如果转化为 Fn = Fn/2*Fn/2+1 + Fn/2-1*Fn/2. 会不会有时间复杂O(logn)的算法。
2)GCD(Fm , Fn)=FGCD( m , n ).
3 ) Fm*n+r = Fr
if m mod 4 = 0.
Fm*n+r = (-1)r+1*Fn-1 if
m mod 4 = 1.
Fm*n+r = (-1)r*Fr
if m mod 4 = 2.
Fm*n+r = (-1)r+1+n*Fn-r if
m mod 4 = 3.
Fibonacci Numbers,形如以下的数列
0,1,1,2,3,5,8,13,21,34, … ,
在这个数列中从第三项开始,每一个元素都是前两个元素的和。
可以写成以下形式:
formula1:
F0 = 0; F1 = 1; Fn+2 = Fn+1 + Fn , n>=0.由此我们就可以得到递归代码:
int Fibonacci_Numbers(int n)
{
if(n==0)
return 0;
if(n==1)
return 1;
return Fibonacci_Numbers(n-1)+Fibonacci_Numbers(n-2);
}
对于上面的算法,经历的时间是指数级的
通过模拟上面的过程可以发现有许多状态是重复的。
我们可以改进上面的过程,改用递推的方式。将原来的状态保留下来,便于以后的使用。
int Fibonacci_Numbers(int n) { int FibNum[MAXSIZE]={0,1}; for(int i=2;i<=n;++i) { FibNum[i]=FibNum[i-1]+FibNum[i-2]; } return FibNum ; }
经过此番改进我们可以得到时间复杂度为O(n)的算法。
但是我们通过另一个关于Fibonacci Numbers表达式可以得到另一个算法。
formula2:
该数学形式表示为:Fn+1 * Fn-1 - Fn2 = (-1)n ,当我们该等式转化为矩阵的形式(此处还不太会数学符号的插入),我们得到一个求解Fibonacci Numbers的可能更有效的算法。
int Fibonacci_Numbers_Matrix(int n) { int FibNumMat[2][2]={1,1,1,0}; int FibNumAns[2][2]={1,1,1,0}; if(n==0) return 0; if(n==1||n==2) return 1; for(int i=0;i<n-2;++i) { int a=FibNumAns[0][0],b=FibNumAns[0][1]; int c=FibNumAns[1][0],d=FibNumAns[1][1]; FibNumAns[0][0]=a*FibNumMat[0][0]+b*FibNumMat[1][0]; FibNumAns[0][1]=a*FibNumMat[0][1]+b*FibNumMat[1][1]; FibNumAns[1][0]=c*FibNumMat[0][0]+d*FibNumMat[1][0]; FibNumAns[1][1]=c*FibNumMat[0][1]+d*FibNumMat[1][1]; } return FibNumAns[0][0]; }
当我们改进成上面的程序时发现并不会比O(n)的算法更优。
如果将 n 表示成 n = b0*20 + b1*21 + b2*22 + ...+ bn*2n .
可以得到一些启示,将上面的程序写成这样子:
int Fibonacci_Numbers(int n) { int FibNumMat[2][2]={1,1,1,0}; int FibNumAns[2][2]={1,0,0,1}; while(n>0) { if(n&1) Matrix((int *)FibNumAns,(int *)FibNumMat),n--; else Matrix((int *)FibNumMat,(int *)FibNumMat),n>>=1; } return FibNumAns[0][1]; } void Matrix(int *Mat1,int *Mat2) { int a1=*Mat1,b1=*(Mat1+1),c1=*(Mat1+2),d1=*(Mat1+3); int a2=*Mat2,b2=*(Mat2+1),c2=*(Mat2+2),d2=*(Mat2+3); *Mat1=a2*a1+c2*b1; *(Mat1+1)=b2*a1+d2*b1; *(Mat1+2)=a2*c1+c2*d1; *(Mat1+3)=b2*c1+d2*d1; }
参考博文:http://blog.csdn.net/y990041769/article/details/22311889
http://blog.csdn.net/liuzhanchen1987/article/details/7712640
此处的时间复杂度应该是O(logn),所用算法思想类似快速幂取模。
此外在书中还有一些有趣的式子。
1 ) Fn+m = Fn*Fn+1 + Fm-1*Fn.
如果转化为 Fn = Fn/2*Fn/2+1 + Fn/2-1*Fn/2. 会不会有时间复杂O(logn)的算法。
2)GCD(Fm , Fn)=FGCD( m , n ).
3 ) Fm*n+r = Fr
if m mod 4 = 0.
Fm*n+r = (-1)r+1*Fn-1 if
m mod 4 = 1.
Fm*n+r = (-1)r*Fr
if m mod 4 = 2.
Fm*n+r = (-1)r+1+n*Fn-r if
m mod 4 = 3.
相关文章推荐
- POJ 1127 Jack Straws [计算几何]
- leetcode 25. Reverse Nodes in k-Group
- Android App开发总结
- 第四周项目5:用递归方法求解(3)求两个数的最大公约数
- 查看git仓库是否有文件未提交
- 第三周学习进度
- SurfaceView有关
- 【机房合作】单例模式的实现(一)
- 初始化一个新的Git仓库
- openssl相关指令及生成私有证书
- HtmlParser基础教程
- UI中常用方法的调用时间
- Harvard architecture
- 中国电影电视奖项
- ExtJs之单选及多选框
- python---游戏登录
- HttpClient使用详解
- 15 API-集合(Collection(功能,迭代器),List(List特有迭代器,并发异常),常见数据结构图示(栈,队列,数组,链表))&对象数组
- Redis开源代码读书笔记五(adlist模块)
- 第4周项目5 返回Fibnacci序列中的第n个数