算法-斐波那契数列(黄金分割数列|兔子数列)

    • 前言

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

    • 题目

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一 对兔子,假如兔子都不死,问每个月的兔子总数为多少?

如图

第一个月是对小兔子 数量:1

第二个月小兔子长大了 数量:1

第三个月大兔子生了小兔子,加上自己本身 数量 2=1+1

第四个月大兔子生一个小兔子(2),第三个月的小兔子长大了(1) 数量:3=2+1

可知每对兔子需要一个月长大,两个月才能生产

根据以上图可以找出规律:当月的兔子数=上个月兔子数+上上月兔子数

    • 代码实现

    • 数组方式:

    public void array(int[] arry){
         //第一月兔子数
         arry[0] = 1;
        //第二月兔子数
         arry[1] = 1;
        for (int i = 2; i < arry.length; i++) {
            arry[i] = arry[i-1]+arry[i-2];
        }
        System.out.println(arry[arry.length-1]);

    }
    • 变量交换(效率高)

方式1

    public int  function(int month){
        //本月兔子数
        int current = 1;
        //上个月兔子数
        int last = 1;
        for (int i = 1; i < month+1; i++) {
            if(i<=2){
                System.out.println(String.format("第%s月,兔子数量%s",i,1));;
                continue;
            }
            //第三个月后的兔子数量 当月兔子数量=上个月兔子数+上上个月兔子数
            current+=last;
            //重新赋值上个月数量 上个月兔子数=当月兔子数量-上上个月兔子数
            last = current-last;
            System.out.println(String.format("第%s月,兔子数量%s",i,current));;
        }
        return current;
    }

方式2

    public int function2(int month){
        if(month==0||month==1){
            return 1;
        }
        //本月兔子数
        int current = 1;
        //上个月兔子数
        int last = 1;
        for (int i = 2; i < month; i++) {
            //第三个月后的兔子数量 当月兔子数量=上个月兔子数+上上个月兔子数
            current+=last;
            //重新赋值上个月数量 上个月兔子数=当月兔子数量-上上个月兔子数
            last = current-last;
        }
        return current;

    }
    • 递归

递归公式:F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

递归需要分析结束条件,通过以上需求分析当第一个月或第二个月时兔子数量都是1,可以当做结束递归条件。

实现逻辑如下图

当第6个月的时返回8个1,f(6)=8

    /**
     * 递归数值过大时效率低
     * @param month
     * @return
     */
    public int recursive(int month) {
        if (month == 1 || month == 2) {
            return 1;
        } else {
            // 递归计算出前一个月和前两个月的合
            return recursive(month - 1) + recursive(month-2 );
        }
    }

测试变量方式1结果如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值