问题描述:斐波那契数列是这样的一个数列,1,1,2,3,5,8,..,即前两项都是1,后面每一项都是其前面两项的和。

现在要你求出该数列的第n项。

分析:该问题是一个经典的数列问题,相信大家在很多语言的教科书上都碰到过这个练习题目。这里我给大家总结了三种经典解法,并对这三个方法进行了对比。

解法一:递归算法。很多教科书上都用这个题作为函数递归知识点讲解的例题,我们可以将每一个项的求法表达为这样一个式子:

f(n)=f(n-1)+f(n-2),f(1)=1,f(2)=1,可以看出,可以采用递归算法求解。

 解法二:循环求法。我们可以从第1项开始,一直求到第n项,即可,一个循环可以做到,时间复杂度为O(n).

解法三:矩阵链乘法。如果线性代数学的好的话,可以想出这样一种解法,

同样可以采用递归的算法求解,时间复杂度为O(logn).

三种解法对比:解法一编程最简单,但是效率最低,因为这种递归算法求解时,会重复求解子问题。如下图示:

这样就看出来吧!另外如果n很大的话,递归的层数很大,会消耗系统大量的时间和资源。

解法二避免了重复求解子问题,线性时间即可求出,值得采用。

解法三效率最高,但是编程特别复杂,在有些情况下,很合适使用,但就本题目来说,推荐解法二。

针对上述三种解法,我给出了详细的Java代码,读者可以参考:

 import java.util.*;
public class Main {
public static int f1(int n){ //方法一:递归算法,自底向上
if(n<=2)return 1; //如果是求前两项,直接返回就可
else return f1(n-1)+f1(n-2);
}
public static int f2(int n){ //方法二:循环算法,自上而下
if(n<=2)return 1; //如果是求前两项,直接返回就可
int a1=1,a2=1,a3;
for(int i=3;i<=n;i++)
{
a3=a1+a2;
a1=a2;
a2=a3;
}
return a2;
}
public static int[][] f3(int n){ //方法三:矩阵链相乘算法,采用递归实现
int a[][]={{1,1},{1,0}}; //定义基矩阵
int b[][]; //存储子方法的结果
int c[][]=new int[2][2]; //存储最后计算结果
int d[][]=new int[2][2]; //存储中间计算结果
if((n)<=1)return a; //如果次方小等于1直接返回
else if((n) %2==1)
{b=f3((n-1)/2); d[0][0]=b[0][0]*b[0][0]+b[0][1]*b[1][0];
d[0][1]=b[0][0]*b[0][1]+b[0][1]*b[1][1];
d[1][0]=b[1][0]*b[0][0]+b[1][1]*b[1][0];
d[1][1]=b[1][0]*b[0][1]+b[1][1]*b[1][1]; c[0][0]=d[0][0]*a[0][0]+d[0][1]*a[1][0];
c[0][1]=d[0][0]*a[0][1]+d[0][1]*a[1][1];
c[1][0]=d[1][0]*a[0][0]+d[1][1]*a[1][0];
c[1][1]=d[1][0]*a[0][1]+d[1][1]*a[1][1]; }
else {
b=f3((n)/2); c[0][0]=b[0][0]*b[0][0]+b[0][1]*b[1][0];
c[0][1]=b[0][0]*b[0][1]+b[0][1]*b[1][1];
c[1][0]=b[1][0]*b[0][0]+b[1][1]*b[1][0];
c[1][1]=b[1][0]*b[0][1]+b[1][1]*b[1][1];
}
return c;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
System.out.println("方法一:"+f1(n));
System.out.println("方法二:"+f2(n));
int a[][]=f3(n-1); //因为是要求矩阵{{1,0},{1,0}}的n-1次方
System.out.println("方法三:"+a[0][0]); } }

输出结果为:

10
方法一:55
方法二:55
方法三:55

求斐波那契数列的第n项的更多相关文章

  1. Problem R: 求斐波那契数列的前n项值

    #include<stdio.h> int main() { int n; while(scanf("%d",&n)!=EOF){ int x1,x2,i,x; ...

  2. 黑马入学基础测试(三)求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

    .获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复 ...

  3. 01-封装函数求斐波那契数列第n项

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  4. C# 求斐波那契数列的前10个数字 :1 1 2 3 5 8 13 21 34 55

    //C# 求斐波那契数列的前10个数字 :1 1 2 3 5 8 13 21 34 55 using System; using System.Collections.Generic; using S ...

  5. 【poj3070】矩阵乘法求斐波那契数列

    [题目描述] 我们知道斐波那契数列0 1 1 2 3 5 8 13…… 数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1). 求斐波那契数列中的第n位mod 10000的值. [ ...

  6. golang 闭包求斐波那契数列

    题目是Go指南中的闭包求斐波那契数列 package main import "fmt" // 返回一个"返回int的函数" func fibonacci() ...

  7. 用JS,求斐波那契数列第n项的值

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. 51 Nod 1242 斐波那契数列的第N项(矩阵快速幂模板题)

    1242 斐波那契数列的第N项  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) ...

  9. 1242 斐波那契数列的第N项

    1242 斐波那契数列的第N项  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题   斐波那契数列的定义如下:   F(0) = 0 F(1) = 1 F(n) = F( ...

随机推荐

  1. nodejs 批处理运行 app.js

    1.直接执行run.bat文件         以下的内容为批处理文件run.bat中的内容,批处理命令中NODE_PATH为Node.js的安装路径. 使用express 生成的项目.app.js为 ...

  2. ERROR 1130: Host is not allowed to connect to this MySQL server

    解决远程连接mysql错误1130代码的方法 今天在用远程连接Mysql服务器的数据库,不管怎么弄都是连接不到,错误代码是1130,ERROR 1130: Host 192.168.2.159 is ...

  3. mvc 5 的过滤器和webapi 过滤器 对应实现的action过滤器区别

     asp.net webapi  Action过滤器实现这个: #region 程序集 System.Web.Http, Version=5.2.3.0, Culture=neutral, Publi ...

  4. Ubuntu自定义命令

    回到主文件夹 $ cd ~ 建立.bash_aliases $ touch .bash_aliases $ vim .bash_aliases 在此文件中加入一句话: alias cdlauncher ...

  5. 你所不了解的css选择器

    我们目前接触到的选择器:.class   #id  div  ...... 不了解的选择器:a>b   a+b [a~=b] [a|=b]......   一下说举5 6 7 8为css3中的定 ...

  6. Jquery根据字段内容设置字段宽度

    来博客园很久了,初次写文章,新手,请大牛见谅! 前段时间遇到的问题,通过gridview后台动态生成table,列和行数量未知,要求根据每个单元格内容的多少,设置宽度,每一列选择本列最大的宽度. ta ...

  7. hdu 2504

    Problem Description 有三个正整数a,b,c(0<a,b,c<10^6),其中c不等于b.若a和c的最大公约数为b,现已知a和b,求满足条件的最小的c. Input 第一 ...

  8. 深入C语言内存区域分配(进程的各个段)详解(转)

    原文地址:http://www.jb51.net/article/39696.htm 一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务) ...

  9. POJ1275/ZOJ1420/HDU1529 Cashier Employment (差分约束)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作, ...

  10. [ofbiz]less-than (&lt;) and greater-than (&gt;) symbols

    问题描述: In field [updateItemStr] less-than (<) and greater-than (>) symbols are not allowed 此处的f ...