斐波那契(Fibonacci)数列

问题描述

递归算法:

 package chapter2shuzizhimei.fibonacci;
/**
* Fibonacci数列递归求解
* @author DELL
*
*/
public class Fibonacci1 {
public static int fibonacci(int n){
if(n<=0)
return 0;
else if(n==1)
return 1;
else
return fibonacci(n-1)+fibonacci(n-2);
}
public static void main(String[] args) {
int n = 3;
System.out.println("fibonacci("+n+") = "+fibonacci(n)); } }

我们的问题是:有没有更加优化的解法?

分析与解法

【解法一】递推关系的优化

上述递归算法中有着很多的重复计算,利用一个数组存储中间结果避免重复计算。时间复杂度为O(N),空间复杂度也为O(N)。

算法如下:

 package chapter2shuzizhimei.fibonacci;
/**
* Fibonacci数列求解
* 【解法一】递推关系的优化
* @author DELL
*
*/
public class Fibonacci2 {
private static int f[];
public Fibonacci2(int n){
f = new int[n+1];
for(int i=0;i<n;i++){
f[i]=-1;
}
}
public static int fibonacci(int n){
if(n<=0){
f[0]=0;
return 0;
}
else if(n==1){
f[1]=1;
return 1;
}
else{
if(f[n-1]==-1){
if(f[n-2]==-1)
return fibonacci(n-1)+fibonacci(n-2);
else
return fibonacci(n-1)+f[n-2];
}else{
return f[n-1]+f[n-2];
}
}
}
public static void main(String[] args) {
int n = 3;
new Fibonacci2(n);
System.out.println("fibonacci("+n+") = "+fibonacci(n)); } }

程序运行结果如下:

fibonacci(3) = 2

【解法二】采用非递归求解

算法如下:

 package chapter2shuzizhimei.fibonacci;
/**
* Fibonacci数列求解
* 【解法二】非递归
* @author DELL
*
*/
public class Fibonacci3 {
public static int fibonacci(int n){
if(n<=0)
return 0;
else if(n==1)
return 1;
else{
int f0 = 0,f1 = 1,f2 = 0;
for(int i=2;i<=n;i++){
f2 = f0 + f1;
f0 = f1;
f1 = f2;
}
return f2;
}
}
public static void main(String[] args) {
int n = 3;
System.out.println("fibonacci("+n+") = "+fibonacci(n)); } }

程序运行结果如下:

fibonacci(3) = 2

【解法三】求解通项公式

算法代码如下:

 package chapter2shuzizhimei.fibonacci;
/**
* Fibonacci数列求解
* 【解法三】求解通项公式
* @author DELL
*
*/
public class Fibonacci4 {
public static long fibonacci(int n){
double x = Math.sqrt(5);
double f = (x/5)*Math.pow((1+x)/2, n) - (x/5)*Math.pow((1-x)/2, n);
return Math.round(f);
}
public static void main(String[] args) {
int n = 3;
System.out.println("fibonacci("+n+") = "+fibonacci(n)); } }

程序运行结果如下:

fibonacci(3) = 2

【解法四】分治策略

要先导入JAMA:Java矩阵包

 package chapter2shuzizhimei.fibonacci;

 import Jama.Matrix;

 /**
* Fibonacci数列求解
* 【解法四】分治策略
* @author DELL
*
*/
public class Fibonacci5 {
//求解矩阵A的n次方
public static Matrix MatrixPow(Matrix A, int n){
int m = A.getColumnDimension();
Matrix result = new Matrix(m,m); //生成全为0的矩阵
for(int i=0;i<m;i++){ //变成单位矩阵
result.set(i, i, 1);
}
Matrix temp = A;
while(n!=0){
if((n&0x01)==1)
result = result.times(temp); //矩阵的乘法
temp = temp.times(temp);
n >>= 1;
}
return result;
}
//计算Fibonacci数列
public static long fibonacci(int n){
if(n<=0)
return 0;
else if(n==1)
return 1;
else{
Matrix A = new Matrix(2,2,1); //生成全为1的矩阵
A.set(1, 1, 0);
Matrix B = MatrixPow(A, n-1);
return (long) B.get(0, 0);
}
}
public static void main(String[] args) {
int n = 5;
System.out.println("fibonacci("+n+") = "+fibonacci(n)); } }

程序运行结果如下:

fibonacci(5) = 5

扩展问题

  假设A(0)=1,A(1)=2,A(2)=2。对于n>2,都有A(K) = A(k-1) + A(k-2) +A(k-3)。

  1. 对于任何一个给定的n,如何计算出A(n)?

  2. 对于n非常大的情况,如n=260的时候,如何计算A(n) mod M (M<100000)呢?

问题1:非递归解法,代码如下:

 package chapter2shuzizhimei.fibonacci;
/**
* 扩展问题1求解
* 非递归
* @author DELL
*
*/
public class Fibonacci6 {
public static int A(int n){
if(n<=0)
return 1;
else if(n==1||n==2)
return 2;
else{
int f0 = 1,f1 = 2,f2 = 2,f3 = 0;
for(int i=3;i<=n;i++){
f3 = f0 + f1 + f2;
f0 = f1;
f1 = f2;
f2 = f3;
}
return f3;
}
}
public static void main(String[] args) {
int n = 4;
System.out.println("A("+n+") = "+A(n)); } }

程序运行结果如下:

A(4) = 9

问题2:非递归解法,代码如下:

 package chapter2shuzizhimei.fibonacci;
/**
* 扩展问题2求解
* 非递归
* @author DELL
*
*/
public class Fibonacci7 {
//计算A(n) mod m
public static long A(long n,long m){
if(n<=0)
return 1;
else if(n==1||n==2)
return 2;
else{
long f0 = 1,f1 = 2,f2 = 2,f3 = 0;
for(int i=3;i<=n;i++){
f0 = f0%m;
f1 = f1%m;
f2 = f2%m;
f3 = f0 + f1 + f2;
f0 = f1;
f1 = f2;
f2 = f3;
}
return f3%m;
}
}
public static void main(String[] args) {
long n = (long) Math.pow(2, 10);
long m = 100;
System.out.println("A("+n+") = "+A(n,m)); } }

程序运行结果如下:

A(1024) = 97

第2章 数字之魅——斐波那契(Fibonacci)数列的更多相关文章

  1. 斐波那契(Fibonacci)数列的几种计算机解法

    题目:斐波那契数列,又称黄金分割数列(F(n+1)/F(n)的极限是1:1.618,即黄金分割率),指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.…….在数学上,斐波纳契数列以如下 ...

  2. 斐波那契(Fibonacci)数列的七种实现方法

    废话不多说,直接上代码 #include "stdio.h" #include "queue" #include "math.h" usin ...

  3. 如何用Python输出一个斐波那契Fibonacci数列

    a,b = 0, 1 while b<100: print (b), a, b = b, a+b

  4. 斐波那契 (Fibonacci)数列

    尾递归会将本次方法的结果计算出来,直接传递给下个方法.效率很快. 一般的递归,在本次方法结果还没出来的时候,就调用了下次的递归, 而程序就要将部分的结果保存在内存中,直到后面的方法结束,再返回来计算. ...

  5. ACM/ICPC 之 数论-斐波拉契●卢卡斯数列(HNNUOJ 11589)

    看到这个标题,貌似很高大上的样子= =,其实这个也是大家熟悉的东西,先给大家科普一下斐波拉契数列. 斐波拉契数列 又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.… ...

  6. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  7. 递归函数练习:输出菲波拉契(Fibonacci)数列的前N项数据

    /*====================================================================== 著名的菲波拉契(Fibonacci)数列,其第一项为0 ...

  8. [洛谷P3938]:斐波那契(fibonacci)(数学)

    题目传送门 题目描述 小$C$养了一些很可爱的兔子.有一天,小$C$突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子 ...

  9. HZOJ 斐波那契(fibonacci)

    先说一个规律: 如图将每个月出生的兔子的编号写出来,可以发现一只兔子在哪一列他的父亲就是谁. 每列的首项可以通过菲波那契求得. 然后你就可以像我一样通过这个规律打表每个点的父亲,预处理出倍增数组,倍增 ...

随机推荐

  1. IOS Swizzle(hook)

    /////////////////////////////////////////////////////////////////////////////////////////////////// ...

  2. Windows7 64位系统下无法安装网络打印机的解决方法

    背景: 公司一台HP LaserJet 1010 打印机连在一台Windows XP的电脑上,而我的是windows7 64位系统,无法安装驱动解决办法:1:去惠普官网上下载对应的64位驱动(什么Vi ...

  3. Android-day02_广播

    1.什么是广播 貌似一个人大声喊一句话,别人听到了这就是广播 2.在android中广播有标准广播和有序广播 标准广播也就是发送一个广播,所有人都能同一时间接收到 有序广播则是有顺序的广播,发送的时候 ...

  4. 【九度OJ】题目1201-二叉排序树

    题目 建树过程是递归,"递归的思路不是很复杂",经过题目1078的训练,直接开始编码.提交及修改的过程告诉自己,这是一个错觉,对递归的理解还应该再进一步. 自己的实现 #inclu ...

  5. 【Hadoop学习】Apache Hadoop ResourceManager HA

    简介 本向导简述了YARN资源管理器的HA,并详述了如何配置并使用该特性.RM负责追踪集群中的资源,并调度应用程序(如MapReduce作业).Hadoop2.4以前,RM是YARN集群中的单点故障. ...

  6. USACO 2013 November Contest Gold 简要题解

    Problem 1. Empty Stalls 扫两遍即可. Problem 2. Line of Sight 我们发现能互相看见的一对点一定能同时看见粮仓的某一段.于是转换成有n段线段,问有多少对线 ...

  7. 第二百九十三天 how can I 坚持

    总感觉怪怪的,换了个领导,好烦,虽然对我没用影响. 其实,还是智商低,不懂人情世故,就像...算了,不说了,只能当自己傻. 最近好冷啊,十年不遇的寒冬. 心情有些压抑. 不玩游戏了,看了集康熙来了.小 ...

  8. 问题-XE8报Object factory for class{xx-xx-xx-xx-xx} is missing. To register it, you can drop component[TFDGUIxWaitCursor] into your project.

    问题现象:XE8开发数据访问程序时放入了FDPhysMSSQLDriverLink1.FDConnection1.FDConnection1.FDQuery1.DBGrid1,设计期没法,运行期报&q ...

  9. scp命令获取远程文件

    一.scp是什么? scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的,可能会稍微影响 ...

  10. Codeforces Round #201 (Div. 2) - C. Alice and Bob

    题目链接:http://codeforces.com/contest/347/problem/C 题意是给你一个数n,然后n个数,这些数互不相同.每次可以取两个数x和y,然后可以得到|x - y|这个 ...