递归求解斐波那契数列的问题

费波那契数列意大利语:Successione di Fibonacci),又译费波拿契数斐波那契数列费氏数列黄金分割数列

数学上,费波那契数列是以递归的方法来定义:

  • F_0=0
  • F_1=1
  • F_n = F_{n-1}+ F_{n-2}(n≧2)

用文字来说,就是费波那契数列由0和1开始,之后的费波那契系数就由之前的两数相加。首几个费波那契系数是(OEIS A000045):

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………

特别指出0不是第一项,而是第零项。

(以上来自维基百科)

求解Fibonacci数列用java的递归很简单:

public static long fibonacci(int n)
    {
        if(n == 0 || n == 1)
        {
            return 1;
        }
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

但用递归求解的效率几乎是无法容忍的,当n为50是,估计需要好几分钟,因为每递归调用一次fibonacci()函数,都会重新计算fibonacci(n - 1)和fibonacci(n - 2),这样有很多数都是重复计算的,一个比较简单的方法就是用一个数据结构将计算后的值缓存起来,

求解时先从缓存里面拿数据,没有的话再计算并将计算后的结果加到缓存里面,这样就避免了很多重复计算。下面是用HashMap将数据缓存的例子:

private static HashMap<Integer, Long> hashMap = new HashMap<Integer, Long>();

private static long value;

 

public static long effectFibonacci(int n)
    {
        if(n == 0 || n == 1)
        {
            return 1;
        }
        if(hashMap.containsKey(n))
        {
            return hashMap.get(n);
        }
        else
        {
            value = effectFibonacci(n - 1) + effectFibonacci(n - 2);
            hashMap.put(n, value);
        }
        return value;
    }

这个算法跟上一个的效率相比有了很大的提高,当n = 1500时,花费的时间大约是 3082077 microseconds,而用上一个递归直接算,不知何年才能得出结果。

 

还有一种求解Fibonacci问题的方法就是利用动态规划算法,动态规划算法是将一个较大的问题分解为若干相似子问题,求解子问题然后合并并得到原问题的解,动态规划算法适用于有重叠子问题和最优子结构性质的问题,重叠子问题即原问题可分解为若干的求解算法相似的子问题,最优子结构就是局部最优导致全局最优,即能够将子问题的解合并后得到原问题的解,这跟贪心算法相似。下面是用动态规划算法求解Fibonacci数列问题:

public static long bestFinabocci(int n)
    {
        long previous = 1, next = 1;
        long tmp = 2;
        for (int i = 2; i <= n; i++)
        {
            tmp = previous + next;  //从2开始,每一个后面的数都是前面两个数之和
            previous = next;
            next = tmp;
        }
        return tmp;
    }

跟上一个使用递归缓存求解,动态规划算法在效率上有了很大的提高,同样当 n = 1500是,递归缓存花费的时间大约是 3082077 microseconds,而动态规划花费的时间大约是 40410 microseconds。

由上面的实验来看,在递归的问题上,最好使用循环代替递归,不得不用到递归时,最好将数据缓存起来避免重复计算,不要直接调用递归函数。

 

转载于:https://www.cnblogs.com/chinayfhuang/p/3614093.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值