算法题-菲波拉契数列问题

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

首先, 由于兔子是成对出现的, 我们在程序只需要考虑兔子是多少对, 而不是多少只。

其实, 对于这种数列求f(n)的问题, 我们的做法是先列出头几个n的值, 然后从中找规律

月份兔子对数分析
111 + 0
211 + 0
321 + 1
432 + 1
553 + 2
685 + 3
7138 + 5
82113 + 8

如上图, 我们下面做看分析

假设f(n) 就是根据月份得出兔子对数的函数

f(1) = f(2) = 1; 是肯定的

当n >= 3 时

我们可以把f(n) 拆分

f(n) = 上个月份的兔子数 + 加上个月份新增的兔子数

其中 上个月份的兔子数 就是 f(n-1)

也就是 f(n) = f(n-1)
问题来了, 上个月份新增的兔子数是什么呢。

我们调用1个具体例子1个例子, 假设g(n) 是第n个月 下个月 新增的兔子数
那么 f(8) = f(7) + g(7) = 13 +8

也就是说g(7) = 8 , 而 f(7) = g(7) + 5 = f(6) + g(6) = 8 + 5

可以看出g(7) = f(6)
也就是讲 g(n) = f(n-1)

可以推导出f(n) = f(n-1) + g(n-1) = f(n-1) + f(n-2)

当前项等于前两项之和, 这就是传说中 Fiboracchi 数列!

当我们推导出规律之后, 程序就很容易写出来了

public class FiboracciSeq {
    public static void main(String... args){
        RabbitCount rb = new RabbitCount();
        List<Integer> rabbitCountList = Arrays.asList(rb.f(1), rb.f(2),rb.f(3),rb.f(4),rb.f(5),rb.f(6));
        rabbitCountList.forEach(System.out::println);
    }

}

/**
 * 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
 * 分析 https://mp.csdn.net/mp_blog/creation/success/127217870
 */
class RabbitCount{

    /**
     *
     * @param n 月份
     * @return 兔子数量
     */
    public int f(int n){
        if (n<3){
            return 1;
        }
        return f(n-1) + g(n-1);
    }

    /**
     *
     * @param n
     * @return n 下个月会新增的兔子数量
     */
    public int g(int n){
        if (n<3){
            return 1;
        }
        return f(n-1);
    }

}

输出:

1
1
2
3
5
8

Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值