斐波那契数列

斐波那契数列

递归实现

/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 递归求菲波那切数列的第N项
 * @param n,无符号的整数,要求的第N项
 * @return 返回第N项
 *  
 */
long long getNthNumberWithRecursion(unsigned int n)
{
    int result[2] = { 0, 1 };
    if (n < 2)
        return result[n];
    return getNthNumberWithRecursion(n - 1) + getNthNumberWithRecursion(n - 2);
}
  • 时间复杂度:
    T(n) = T(n - 1) + T(n - 2) + O(1),很容易得到T(n) = O(1.618 ^ n)(黄金分割点,(1+5√)/2 )
  • 空间复杂度取决于递归的深度是 O(N)

迭代实现

/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 迭代求菲波那切数列的第N项
 * @param n,无符号的整数,要求的第N项
 * @return 返回第N项
 *  
 */
long long getNthNumberWithNoRecursion(unsigned int n)
{
    int result[2] = { 0, 1 };
    if (n < 2)
        return result[n];
    long long total = 0, first = 0, second = 1;
    for (unsigned int i = 2; i <= n; i++)
    {
        total = first + second;
        first = second;
        second = total;
    }
    return total;
}

-时间复杂度: O(N)
-空间复杂度: O(1)

矩阵实现

我们把Fibonacci数列中相邻的两项:F(n)和F(n - 1)写成一个2x1的矩阵,然后对其进行变形

[FnF(n1)]=[F(n1)+F(n2)F(n1)]=[1×F(n1)+1×F(n2)1×F(n1)+0×F(n2)]=[1110]×[F(n1)F(n2)]

上面的式子可以继续化简
[FnF(n1)]=[1110]n1×[F1F0]=[1110]n1×[10]

呃呃。。。
只要对这个二阶方阵求n - 1次方,最后取结果方阵第一行第一列的数字就是 Fn 的值。
注意:幂运算是可以二分加速的。
an= an/2×an/2,an/2×an/2×a,n  n 

所以,时间复杂度是 logN

/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 二维矩阵
 *  
 */
struct Matrix2By2
{
    long long m_00;
    long long m_01;
    long long m_10;
    long long m_11;

    Matrix2By2
        (
        long long m00 = 0,
        long long m01 = 0,
        long long m10 = 0,
        long long m11 = 0
        )
        :m_00(m00), m_01(m01), m_10(m10), m_11(m11){}
};


/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 矩阵相乘
 * @param 两个矩阵
 * @return 矩阵相乘的结果矩阵
 *  
 */
Matrix2By2 MatrixMultiply(const Matrix2By2& matrix1,const Matrix2By2& 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);
}

/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 矩阵的N次方
 * @param 
 * @return
 */
Matrix2By2 MatrixPower(unsigned int n)
{
    assert(n > 0);

    Matrix2By2 matrix;
    if (n == 1)
    {
        matrix = Matrix2By2(1, 1, 1, 0);
    }
    else if (n % 2 == 0)
    {
        matrix = MatrixPower(n / 2);
        matrix = MatrixMultiply(matrix, matrix);
    }
    else if (n % 2 == 1)
    {
        matrix = MatrixPower((n - 1) / 2);
        matrix = MatrixMultiply(matrix, matrix);
        matrix = MatrixMultiply(matrix, Matrix2By2(1, 1, 1, 0));
    }

    return matrix;
}

/**
 * @author 韦轩
 * @time 2015/07/26
 * @brief 使用矩阵计算获得菲波那切数列的第N项
 * @param 
 * @return
 *  
 */
long long getNthNumberWithMatrix(unsigned int n)
{
    int result[2] = { 0, 1 };
    if (n < 2)
        return result[n];

    Matrix2By2 PowerNMinus2 = MatrixPower(n - 1);
    return PowerNMinus2.m_00;
}
  • 时间复杂度: O(logN)
  • 空间复杂度: O(1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值