题目:
- 使用递归和非递归的方法分别实现求第n个斐波那契数,那么什么是斐波那契数。斐波那契数列指的是这样一个数列:0 、1、1、2、3、5、8、13、21,后面的每一个数是前面两个数的和。(由于数列增长快,int型就只能算到近50位,所以尽可能采用long long型)*
方法一:递归实现
//时间复杂度O(N^2)
//空间复杂度o(N)
long long fib(size_t n)
{
return (n < 2) ? n : (fib(n - 1) + fib(n - 2));
}
缺点:
①只是使用于n比较小的时候,否则效率低,因为会做很多次重复操作
②而且该例递归属于多分支递归,容易造成栈溢出
方法二:非递归实现(迭代)
//时间复杂度O(N)
//空间复杂度O(1)
long long fib(size_t n)
{
long long n1 = 0,n2= 1,n3=n;
int i = 0;
for(i = 2;i<=n;i++)
{
n3 = n1+n2;
n1 = n2;
n2 = n3;
}
return n3;
}
方法三:尾递归实现
//时间复杂度O(N)
long long fib(long long first,long long second,size_t n)
{
if(n<2)
{
return n;
}
if(2 == n)
{
return first+second;
}
return fib(second,first+second,n-1);
}
优点:
①计算结果参与到下一次的计算,从而减少很多重复计算量
②原本朴素的递归产生的栈的层次像二叉树一样,以指数级增长,但是现在栈的层次却像是数组,变成线性增长了,简单来说,原本栈是先扩展开,然后边收拢边计算结果,现在却变成在调用自身的同时通过参数来计算。
尾递归可以转换成迭代算法
总结:
尾递归的本质是:将单次计算的结果缓存起来,传递给下次调用,相当于自动累积
方法四:矩阵乘法实现 (最优解)
- 常识:
- 快速幂:
#include <stdio.h>
//base 底数 ,exp 指数
int qpow(int base,int exp)
{
if (0==exp ) return 1;
int ret=1;
while(exp)
{
if(exp&1)//exp最右边一位 按位与&
{
ret=ret*base;
}
base=base*base;
exp>>=1;//右移一位
}
return ret;
}
int main()
{
printf("%d",qpow(3,5));
return 0;
}
注:此方法借鉴与 谷歌面试题精选
#include<iostream>
#include<string>
using namespace std;
//定义2×2矩阵;
struct Matrix2by2
{
//构造函数
Matrix2by2
(
long m_00,
long m_01,
long m_10,
long m_11
)
:m00(m_00),m01(m_01),m10(m_10),m11(m_11)
{
}
//数据成员
long m00;
long m01;
long m10;
long m11;
};
//定义2×2矩阵的乘法运算
Matrix2by2 MatrixMultiply(const Matrix2by2& matrix1,const Matrix2by2& matrix2)
{
Matrix2by2 matrix12(1,1,1,0);
matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10;
matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11;
matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10;
matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11;
return matrix12;
}
//定义2×2矩阵的幂运算
Matrix2by2 MatrixPower(unsigned int n)
{
Matrix2by2 matrix(1,1,1,0);
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;
}
//计算Fibnacci的第n项
long Fibonacci(unsigned int n)
{
if(n == 0)
return 0;
if(n == 1)
return 1;
Matrix2by2 fibMatrix = MatrixPower(n-1);
return fibMatrix.m00;
}
int main()
{
cout<<"Enter A Number:"<<endl;
unsigned int number;
cin>>number;
cout<<Fibonacci(number)<<endl;
return 0;
}
结语:
努力的人生是完美的,因为不曾后悔过!!!