前阵子,日剧“轮到你了”终于大结局了,虽然结局有点一言难尽,但黑岛和二阶堂两个学霸之间的爱情,还是很甜呢呐!两个学霸之间的默契的斐波那契数列也被许多网友认为是凶手行凶的依据。到底这数列有啥神奇之处,又该如何使用代码实现呢?一起往下看吧!斐波那契数列,又称黄金分割数列,指的是这样一个数列:1,1,2,3,5,8,13,21,34,55…… 我们不难发现从第三项开始,每一项都等于前两项之和。以递归的方法定义就是F0=0,F1=1,Fn=Fn-1+Fn(n>=2,n∈N*)。(为了与数组下标的概念对应,F0为第0项)。通过上面的解释,相信你对斐波那契数列有一定的了解了吧,那我们来看看今天的题目吧。今天的题目就是:当你输入一个整数n后,输出斐波那契数列的第n项(从0开始,第0项为0,n<=39)。脑袋里有什么想法了么?没有的话来看看下面的三种解法吧。一、递归解法斐波那契数列具有天然的递归性,根据数学上的定义,可以得出其递推公式为:Fn=Fn-1+Fn-2(n>=2,n∈N*),基础情况为 F0=1,F1=1。对于递归解法,我们可以把问题转化为规模缩小了的同类问题的子问题,找出明确的不需要继续进行递归的条件(即基本情况base case),在本题中的基本情况为F0=0,F1=1, 当递归至基本情况后,无需继续递归,最后把子问题的解汇聚成大问题的解。可画递归树解决递归问题

public class Solution {    public int Fibonacci(int n) {        //base case        if (n==0){           return 0;       }        if(n==1){            return 1;        }       return Fibonacci(n-1)+Fibonacci(n-2);    }}

复杂度分析:

①子问题个数,即递归树中节点的总数,而二叉树节点总数为指数级别,所以子问题个数为 O(2^n);而解决一个子问题的时间,在本算法中,没有循环,只有 f(n - 1) + f(n - 2)f(n−1)+f(n−2) 一个加法操作,所以时间为O(1)。故我们可以得到这个算法的时间复杂度为 O(2^n),指数级别。

②而在递归过程中,需要在存储递归过程中的运算结果,最大空间为树的高度h(即n),而时间复杂度:O(2^n),故空间复杂度:O(h) 即O(n)问题分析:观察递归树,很明显发现了算法低效的原因:存在大量重复计算,运算的规模与n的大小成指数关系,因此这个暴力递归算法虽然简洁明了,但运行效率低下。二、动态分析由于暴力递归存在大量的重复运算,降低了算法的性能。所以我们可以用动态规划方法,把运算结果存储起来,从第0项推导至第n项,避免重复运算。我们可以先思考其暴力递归的解法,把暴力递归的过程抽象成状态转移方程,确定可变参数,从基本情况(base case)开始推理,通过状态转移方程,得出最优解,从而减少冗余运算。

public class Solution {      public  int Fibonacci(int n) {        //基本情况        if (n==0){            return 0;        }        if (n<=1){            return 1;        }        int dp[]=new int[n+1];        dp[0]=0;        dp[1]=1;        for(int i=2;i            //状态转移方程            dp[i]=dp[i-1]+dp[i-2];        }        return dp[n];    }}

复杂度分析:  需要开辟长度为n+1的dp数组,同时遍历整个数组,故时间复杂度为O(n),空间复杂度为O(n)。

细心的你会发现,根据斐波那契数列的状态转移方程,当前状态只和之前的两个状态有关,其实并不需要那么长的一个 DP 数组来存储所有的状态,只要想办法存储之前的两个状态就行了。所以可以进一步优化,把空间复杂度降为 O(1)。

三、斐波那契数列通项公式 对于这道题目,我们还可以通过斐波那契数列通项公式求解,但这个数学方法仅限于标准的斐波那契数列问题求解,无法应对斐波那契数列的变种问题。公式如下: 

public class Solution {    public  int Fibonacci(int n) {      Long fib = Math.round((Math.pow((1 + Math.sqrt(5)) / 2, n)                              - Math.pow((1 - Math.sqrt(5)) / 2, n))                             / Math.sqrt(5));         return fib.intValue();    }}

复杂度分析:将n代入公式即可得到答案,其中Math.pow(a,b)为求a的b次方、Math.sqrt(a)为求a的正平方根、Math.round(a)为取a最接近的整数(可简单理解为四舍五入取整).对于pow、sqrt、round方法,我们都可以放心地认为其时间复杂度为O(1),因而总的时间复杂度为O(1)。我们使用变量fib存储运算结果,因此空间复杂度为O(1)。               斐波那契数列来自实现生活,有着诸多的变种问题,例如自然界中向日葵花蕊的排列线条顺时针排列线条数为21,逆时针排列线条数为34,是两个相邻的斐波那契数;树木也是以斐波那契数列的方式生长;而黄金比例也经常被用于艺术和建筑的设计,规划和建造许多建筑物,如教堂,寺庙,祭坛,住房以及创造宗教艺术品。(但其实, 斐波那契数列在“轮到你了”就真的只是个数列。)

更多精彩内容:

(点击即可阅读)

用两个栈实现队列用队列实现栈持续更新中.....后续我们还会持续更新一些有意思的算法基础题目,有兴趣的可以持续关注一下~ 信析团队持续招新,有兴趣了解的小可爱可以来科技楼232详谈哦(*╹▽╹*)祝祖国生日快乐! !

斐波那契数列c++代码_轮到你了,斐波那契数列!相关推荐

  1. 无源波分和彩光模块_【光电通信】无源波分在 5G 场景中 的应用分析

    今日光电        有人说,20世纪是电的世纪,21世纪是光的世纪:知光解电,再小的个体都可以被赋能.欢迎来到今日光电! ----与智者为伍 为创新赋能---- 无源波分在 5G 场景中 的应用分 ...

  2. B站JavaScript从入门到精通智能社Blue石川老师视频部分代码_轮播图

    从三月底开始,慢慢地上手了JavaScript,去年在学校放假前也看了一套视频,总感觉好像是会了又好像不会,现在看了Blue老师的视频,感觉思路清晰多了,也终于算是入门了吧. 接下来我会把学习过程中跟 ...

  3. 数学编程:经典数学编程案例之斐波那契:斐波那契数列的简介、代码实现、exe程序应用(斐波纳契时钟设计)之详细攻略

    数学编程:经典数学编程案例之斐波那契:斐波那契数列的简介.代码实现.exe程序应用(斐波纳契时钟设计)之详细攻略 目录 斐波那契数列的简介 斐波那契数列代码实现 1.python代码实现 2.Java ...

  4. 循环斐波那契数列_第五课:斐波那契数列(第一课时)

    简介:又称黄金分割数列.因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为"兔子数列",指的是这样一个数列:1.1.2.3.5.8.13.21.34--在数学上,斐波那契数 ...

  5. python兔子繁殖问题中如何输出相应月份的数列_斐波那契数列介绍及Python中五种方法斐波那契数列...

    Q:斐波那契数列为何那么重要,全部关于数学的书几乎都会提到? A:由于斐波那契数列在数学和生活以及天然界中都很是有用.html 1. 斐波那契数列 概念引入 斐波那契数列(Fibonacci sequ ...

  6. 如何用python求斐波那契数列_如何使用Python实现斐波那契数列

    斐波那契数列(Fibonacci)最早由印度数学家Gopala提出,而第一个真正研究斐波那契数列的是意大利数学家 Leonardo Fibonacci,斐波那契数列的定义很简单,用数学函数可表示为: ...

  7. 用python语言编斐波那契数列_用python函数写斐波那契数列

    斐波那契数列,又称黄金分割数列.因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为"兔子数列",指的是这样一个数列:1.1.2.3.5.8.13.21.34.--在数学上, ...

  8. 数字拆分为斐波那契数列_检查数字是否为斐波那契

    数字拆分为斐波那契数列 Description: 描述: We are often used to generate Fibonacci numbers. But in this article, w ...

  9. 斐波那契数列不用数组_兔子数列——斐波那契数列

    相信人们都对斐波那契数列有或多或少的了解,如果没有,那你一定听过黄金分割比或是见过下面这种图片: 斐波那契生活在十三世纪的意大利,原名列奥纳多·皮萨诺(Leonardo Pisano),他出生在意大利 ...

最新文章

  1. lisp修改天正标高值_【求教】如何批量修改天正字体
  2. Flask实战2问答平台-首页布局,功能完成
  3. Spring-Security 自定义Filter完成验证码校验
  4. git管理账户忘记了_强制找回GitLab管理员账户密码的方法
  5. LeetCode MySQL 1435. 制作会话柱状图
  6. linux卡死在选择内核界面,求助:am3352 linux内核启动时卡在 Starting kernel ...
  7. 你百分之九十九的问题都是因为懒
  8. 快速构建Windows 8风格应用5-ListView数据控件
  9. AD域控exchange邮箱(一)——批量安装MSI安装包
  10. Hadoop Shell 命令详解
  11. Euraka和ZOOkeeper比较
  12. 小米airdots2蓝牙耳机连上手机后没有声音
  13. 手机移动OA:指尖上也可以拥有会议助手
  14. 趋势交易中区间跨度的定义
  15. 数值计算笔记-部分主元消去cholesky分解
  16. Android游戏源码合集(主要是AndEngine和Libgdx的)
  17. 如何更加深入地学习Python?
  18. Matplotlib.pyplot 常用方法
  19. 小程序带参数二维码生成接口
  20. 萝卜和青菜--Android camera框架与使用

热门文章

  1. 细数家庭安防五大乱象 何时能步入正轨
  2. Oracle按用户进行统计信息更新
  3. SQL Server Insert 操作效率(堆表 VS 聚集索引表)
  4. oracle低权限下获取shell
  5. I2C总线之(三)---以C语言理解IIC
  6. dm368ipnc 重写架构中的swosd 实现中文osd
  7. CST光源控制卡简单操作C#程序
  8. halcon Bit图位像素处理算子,持续更新
  9. 【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)
  10. stdout标准输出、stderr标准错误输出 标准输入、标准输出、标准错误输出分别被定义为0、1、2。