[置顶] 【算法】Fibonacci解法总结
2015-10-30 13:10
274 查看
我这里说的Fibonacci数列不仅仅是f(n-1) + f(n-2)的情况,也可以是f(n-1) + f(n-2) + … + f(n-k)的情况。但是这里我们用f(n-1) + f(n-2)来进行讨论,简化理解,举一反三。
这种解法与递归解法相比,具有非常大的性能提升。
Fibonacci问题还可以用来解上台阶问题,硬币面值组合问题。
解法一,递归
实现非常简单。int fibonacci(int i){ if(i==0){ return 0; }else if(i==1){ return 1; }else { return fibonacci(i-1)+fibonacci(i-2); } } }
解法二,动态规划
核心代码如下:long array[]=new long [n+1]; array[0]=0; array[1]=1; for(int i=2;i<n+1;i++){ array[i]=array[i-1]+array[i-2]; }
这种解法与递归解法相比,具有非常大的性能提升。
解法三,动归优化
将空间优化到O(1):int fib(int n) { int last, nextToLast, answer = 0; if (n <= 1) { return 1; } last = nextToLast = 1; for (int i = 0; i < n; i++) { //f(n)=f(n-1)+f(n-2) answer = last + nextToLast; //f(n-2)=f(n-1) nextToLast = last; //f(n-1)=f(n) last = answer; } return answer; }
解法四,特殊解法
这种解法可以将时间复杂度优化到O(logn),牛客网的左老师书上讲的非常清楚,这里直接借助过来以供参考:/* 下面介绍一种时间复杂度是O(logn)的方法: 对于斐波那契数列1,1,2,3,5,8,13…….有如下定义: F( n ) = F( n-1 ) + F( n-2 ) F( 1 ) = 1 F( 2 ) = 1 矩阵形式: [ F( n+1 ) , F( n ) ] = [ F( n ) , F( n-1 ) ] * Q 其中 [ F( n+1 ) , F( n ) ]为行向量,Q = { [ 1, 1 ]; [ 1, 0 ] }为矩阵 则 [ F( n+1 ) , F( n ) ]=[ 1 , 0 ] * Qn , */ struct Matrix { long long m_00, m_01, m_10, m_11; Matrix ( long long m00 = 0, long long m01 = 0, long long m10 = 0, long long m11 = 0 ) :m_00( m00 ), m_01( m01 ), m_10( m10 ), m_11( m11 ) { } }; Matrix MatrixMultiply ( const Matrix & m1, const Matrix & m2 ) { long long m00 = m1.m_00 * m2.m_00 + m1.m_01 * m2.m_10; long long m01 = m1.m_00 * m2.m_01 + m1.m_01 * m2.m_11; long long m10 = m1.m_10 * m2.m_00 + m1.m_11 * m2.m_10 long long m11 = m1.m_10 * m2.m_01 + m1.m_11 * m2.m_11; return Matrix ( m00, m01, m10, m11 ); } Matrix MatrixPower( unsigned int n ) { assert(n > 0); Matrix m; if( n == 1) { m = Matrix(1, 1, 1, 0); } else if(n % 2 == 0) { m = MatrixPower( n / 2 ); m = MatrixMultiply( matrix, matrix ); } else if( n % 2 == 1 ) { m = MatrixPower( (n - 1) / 2 ); m = MatrixMultiply( m, m ); m = MatrixMultiply( m, Matrix( 1, 1, 1, 0 ) ); } return m; } long long Fibonacci( unsigned int n ) { int result[2] = { 0, 1 }; if( n < 2 ) return result[ n ]; Matrix Q = MatrixPower( n - 1 ); //注意:按定义式应该用[ 1, 0 ]*Q, 或者等价于{ [ 1 , 0 ]; [ 0, 0 ] }*Q, 但是因为显然结果相同,所以略去这一步。 return Q.m_00; }
总结
我觉得Fibonacci数列对于理解动态规划也是非常重要,动态规划的本质就是在递归中优化而来的。Fibonacci问题还可以用来解上台阶问题,硬币面值组合问题。
相关文章推荐
- ipad2越狱了 图标分得很开 点程序就重启
- Hadoop 1.x 伪分布式部署与测试
- 你还在我身旁
- c++内存池工作原理
- codeforces 19E Fairy 树链剖分
- VVDocumenter-Xcode
- VVDocumenter-Xcode
- Java获取时间并将时间格式化输出以为文件名
- eclipse如何关联源码
- Reverse Integer
- Shiro 缓存失效以后的一个问题
- tornado.gen 模块解析
- Java根据两点的经纬度来计算之间的距离
- Oracle round()函数与trunc()函数区别介绍
- object_getClass
- 关于ios中的点赞控件效果的实现--UIControl
- spark数据挖掘 - 基于 Audioscrobbler 数据集音乐推荐实战
- DRBD原理及特性概述
- oracle恢复备份数据
- 多子系统项目架构与人员管理