zoukankan      html  css  js  c++  java
  • 一般Fibonacci算法的优化

    一般的Fibonacci算法:

    int Fibonacci(int number)
    {
        if (number < 2) return number;
        return Fibonacci(number - 1) + Fibonacci(number - 2);
    }

    该算法的时间复杂度达到了惊人的指数级别,效率慢的不行,下面提供两种不同的改进方式,时间复杂度分别为O(n)和O(logn)。

    方法一:O(n)

    int Fibonacci(int number)
    {
        if (number < 2) return number;
    
        int fibonacci[2] = {0, 1};
        int result = 0;
        for (int index = 2; index <= number; ++index) {
            result = fibonacci[0] + fibonacci[1];
            fibonacci[0] = fibonacci[1];
            fibonacci[1] = result;
        }
        return result;
    }

    将原本的自顶向下计算的方式,改为自底向上,消除原本过多的冗余计算,来降低时间复杂度。

    方法二:O(logn)

    数据结构:

    struct Matrix2By2
    {//second order matrix
    public:
        Matrix2By2(int m00 = 1, int m01 = 1, int m10 = 0, int m11 = 0)
          :m_00(m00), m_01(m01), m_10(m10), m_11(m11) {}
    
    public:
        int m_00;
        int m_01;
        int m_10;
        int m_11;
    };
    
    Matrix2By2 MatrixMultiply(const Matrix2By2& matrix1, const Matrix2By2& matrix2)
    {//matrix1 multiply matrix2
        return Matrix2By2(matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,
                          matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,
                          matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,
                          matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);
    }
    

    递归方式:

    Matrix2By2 MatrixPower(Matrix2By2 matrix, int exponent)
    {//matrix exponentation
          if(1 == exponent) return matrix;
    
          if(exponent & 1) {
              return MatrixMultiply(MatrixPower(MatrixMultiply(matrix, matrix), exponent >> 1),
                                    matrix);
          } else {
              return MatrixPower(MatrixMultiply(matrix, matrix), exponent >> 1);
          }
    }
    
    int Fibonacci(int number)
    {
        if (number < 2) return number;
    
        //initialization
        Matrix2By2 matrix = Matrix2By2(1, 1, 1, 0);
    
        matrix = MatrixPower(matrix, number - 1);
    
        return matrix.m_00;
    }

    非递归方式:

    int Fibonacci(int number)
    {
        if (number < 2) return number;
    
        //initialization
        Matrix2By2 matrix(1, 1, 1, 0);
        Matrix2By2 result(1, 0, 1, 0);
        int exponent = number - 1;
    
        while (exponent) {
            if (exponent & 1) {
                --exponent;
                result = MatrixMultiply(result, matrix);
            }
            matrix = MatrixMultiply(matrix, matrix);
            exponent = exponent >> 1;
    
        }
        return result.m_00;
    }

    利用了{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1的性质,实际上就是2阶矩阵(a11 = 1, a12 = 1, a21 = 1, a22 = 0)的n-1次幂,fibonacci(n)为该矩阵n-1次幂的a11。

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/wolves-dave/p/3297567.html
Copyright © 2011-2022 走看看