算法学习系列之找出斐波那契数

特别说明:本文参考学习于Java语言程序设计进阶篇—Y.Daniel Liang著一书
欢迎大家一起学习交流,希望程序的世界有你相伴

题目

给出下标index,找出斐波那契数列下标为index的值,斐波那契数列为: {1,1,2,3,5,8…},前两位为1,随后的值均为在它前面的两个数的和。

解法

方法1

利用斐波那契数列的构造原理,我们很容易写出如下的递归算法解决该问题

    public static long fib1(int index) {
        if (index == 0)
            return 0;
        else if (index == 1)
            return 1;
        else
            return fib1(index - 1) + fib1(index - 2);
    }

时间复杂度

令下标为n,假设T(n)表示找出fib1(n)的算法的复杂度,而c表示比较下标为0的数和下标为1的数耗费的常量时间,也就是说T(1)是c。因此

T(n)=T(n-1) + T(n-2) + c 
    <= 2*T(n-1) + c 
    <= 2*(2*T(n-2)+c) + c 
    = 2^2 *T(n-2) + 2c + c
    ...
    = 2^(n-1) *T(1) + (n-1)c + ... + c

可以发现T(n) 的O(2^n)。

可改进点

这个算法的效率并不高,递归的fib1()方法中存在的问题在于冗余地调用同样参数的方法。例如,为了计算fib1(4),要调用fib1(3)和fib1(2)。为了计算fib1(3),要调用fib1(2)与fib1(1)。注意fib1(2)被调用多次。我们可以通过避免这样重复调用同样的参数的fib1方法来提高算法效率。注意,一个新的斐波那契数是通过对数列中的前两个数相加得到的。如果用两个变量f0和f1来存储前面两个数,那么可以通过将f0和f1相加立即获得新数f2。这样,我们可以通过构建斐波那契数列的同时,得到该题的高效率的解法。

方法2

    public static long fib2(int index) {
        long f0 = 0;
        long f1 = 1;
        long f2 = 1;

        if (index == 0)
            return f0;
        else if (index == 1)
            return f1;
        else if (index == 2)
            return f2;

        for (int i = 3; i <= index; i++) {
            f0 = f1;
            f1 = f2;
            f2 = f0 + f1;
        }

        return f2;
    }

显然这样的算法的时间复杂度是O(n),这比方法1中的算法高效很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值