zoukankan      html  css  js  c++  java
  • 聊聊斐波那契数列中递归的重复计算

    聊聊斐波那契数列中递归的重复计算

    聊聊斐波那契数列中递归的重复计算

    所谓的斐波纳契数列是指:

    前2个数是 0 和 1 。
    第 i 个数是第 i-1 个数和第i-2 个数的和。
    斐波纳契数列的前10个数字是:

    0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...

    1 递归实现

    根据定义,很快就能写出递归实现:

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

    但是,这个函数去执行的时候,会发现非常的慢。那是什么原因呢?
    我们仔细观察一下,每一次递归的时候,我们都会调用两个,所以,计算时,从n、n-1、… 0会是一个金字塔,二叉树的分布,也就是靠近0的底层,会有2^n次运算,就是一个指数级运算,计算时间复杂度为O(2^n),运算速度是非常慢的。
    原因是什么呢?假如,我们计算的是10,那么它相应的要计算 9 + 8,而9要计算 8 + 7, 8又要计算 7 + 6.相当于越往底层去,计算的次数越多。

        10
       /  
      9    8
     /   / 
    8   7 7  6
        ...
    

    2 递归改进

    那么避免重复计算的方法就是,每计算得到一个值,便用一个数组保存这个值,下次计算该值的时候直接引用就可以了。

    public int fibonacci(int n) {
        int[] array = new int[n + 1];
    
        if (n < 2) {return 0;}
        if (2 == n) {return 1;}
        array[1] = 0;
        array[2] = 1;
    
        return helper(array, n);
    }
    
    private int helper(int[] array, int n) {
        if (n < 2) {
            return 0;
        }
        if (2 == n) {
            return 1;
        }
        array[n] = helper(array, n - 1) + array[n - 2]; // 保存每次计算的结果
        return array[n];
    }
    

    但这种方法不是尾递归的,所以,调用栈内存会比较多。

    3 迭代法

    用迭代法来计算是最简单,速度也最快的。

    public int fibonacci(int n) {
        int[] array = new int[n + 1];
    
        if (n < 2) {return 0;}
        if (2 == n) {return 1;}
        array[1] = 0;
        array[2] = 1;
    
        for (int i = 3; i <= n; i++) {
            array[i] = array[i - 1] + array[i - 2];
        }
    
        return array[n];
    
    }
    

    Date: 2017-07-02 10:55

    Author: WEN YANG

    Created: 2017-07-02 Sun 13:01

    Emacs 25.2.1 (Org mode 8.2.10)

    Validate

  • 相关阅读:
    Html5响应式设计与实现广场
    hdu 4911 Inversion
    LAN远程重启server安全方法
    华丽的网上突出代码组件CodeMirror
    Edit Distance -- LeetCode
    FPGA合成编码
    SenchaTouch2.3.1 正在使用listpaging以及pullrefresh插入 分页演示样品做
    【白云观导引头】一首诗
    初步boost之pool图书馆学习笔记
    分段的作用
  • 原文地址:https://www.cnblogs.com/yangwen0228/p/7105751.html
Copyright © 2011-2022 走看看