打印斐波那契数列(C++代码实现)

题目来源:力扣
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

一、递归

最容易想到的方法,也是一种很经典的解法,问题是时间复杂度为指数级,空间效率与时间效率都很低,面试官一般不喜欢,而且力扣也过不去。
下面展示 代码

int fib(int n) {
if (n == 0 || n == 1)
	{
		return n;
	}
	return fib(n - 1) + fib(n - 2);
}

二、动态规划

面试官能接受的一种方法,也是很常规的方法,首先创建一个数组存储斐波那契数列fib,然后遍历数组,利用递推式子
fib[i]=fib[i-1]+fib[i-2]填充数组。代码如下:

int fib(int n)
{
	if (n <= 1)
		return n;
	vector<int> fib(n + 1);
	fib[0] = 0;
	fib[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		fib[i] = fib[i - 1] + fib[i - 2];
	}
	return fib[n];
}

时间复杂度为O(n),空间复杂度也为O(n),相对于第一种递归法来说,时间效率略高。

三、改进递推

这种方法不太实用,但是能够使求解斐波那契数列的时间复杂度为对数级别,主要利用的是下式:
[ f ( n ) f ( n − 1 ) f ( n − 1 ) f ( n − 2 ) ] = [ 1 1 1 0 ] n − 1 \begin{bmatrix}f(n) &f(n-1) \\ f(n-1)&f(n-2) \end{bmatrix}=\begin{bmatrix} 1&1 \\ 1&0 \end{bmatrix}^{n-1} [f(n)f(n1)f(n1)f(n2)]=[1110]n1
将求解f(n)转换成求解矩阵的乘方,在求解乘方的时候,若只是简单的从0开始循环,时间复杂度仍然是O(n),但是可以考虑乘方的如下性质:
在这里插入图片描述
最终实现代码如下:

//创建目标矩阵
vector<vector<double>> creatmatrix()
{
	vector<vector<double>> v;
	vector<double>v1 = { 1,1 };
	v.push_back(v1);
	v1 = { 1,0 };
	v.push_back(v1);
	return v;
}
//矩阵A*矩阵B=矩阵C,并返回
vector<vector<double>> multiplybase(const vector<vector<double>>& A, const vector<vector<double>>& B)
{
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();
	if (A_l != B_h)
	{
		cout << "两矩阵维数无法相乘" << endl;
		exit(0);
	}
	vector<vector<double>> C = creatmatrix(A_h, B_l);
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i][j] = 0;
			for (int k = 0; k < A_l; k++)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
			//cout<<C[i][j]<<"\t";
		}
		//cout<<endl;
	}
	return C;
}
vector<vector<double>> multiply(const vector<vector<double>>& A, int n)
{
	if (n == 1)
	{
		return A;
	}
	vector<vector<double>> temp = multiply(A, n / 2);
	if (n % 2 == 1)
	{
		return multiplybase(multiplybase(temp, temp), A);
	}
	return multiplybase(temp, temp);
}

int fib(int n)
{
	vector<vector<double>> base = creatmatrix(2, 2);
	vector<double> result = multiply(base, n - 1)[0];
	return result[0];
}

有关递归复杂度的讲解,请看
https://blog.csdn.net/weixin_60655522/article/details/126061250

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值