【演算法詳解】斐波那契數列 - Fibonacci sequence

王曉斌發表於2014-02-16

1. 斐波那契數列定義



線上測試工具: http://zh.numberempire.com/fibonaccinumbers.php


2. 演算法

求解斐波那契數列的第n個數:


2.1 遞迴/分治法

#include <cstring>
#include <iostream>

using namespace std;

unsigned long fabinacci(unsigned int n)
{
	if (n == 0)
	{
		return 0;
	}else
	if (n == 1)
	{
		return 1;
	}else
	{
		return fabinacci(n - 2) + fabinacci(n - 1);
	}
}

int main() 
{
	unsigned int n = 0;
	cout<<"Please input a unsigned integer:"<<endl;
	cin>>n;
	cout<<"The "<<n<<"th fabonacci element is: "<<fabinacci(n);
	return 0;
}

遞迴效率分析:

以計算f(10)為例:


從圖中可以看出:要計算很多重複的之,計算重複值的數量隨著N值而急劇增大。事實上該演算法的時間複雜度隨著n值呈指數增長 O((3/2)^n)


2.2 迭代求解

迴圈求解:
#include <cstring>
#include <iostream>

using namespace std;

long long fabinacci(unsigned int n)
{
	if (n == 0)
	{
		return 0;
	}else
	if (n == 1)
	{
		return 1;
	}

	long long first = 0;
	long long second = 1;

	for (unsigned i = 1; i < n; i++)
	{
		second = first + second;
		first = second - first;
	}

	return second;
}

int main() 
{
	unsigned int n = 0;
	cout<<"Please input a unsigned integer:"<<endl;
	cin>>n;
	cout<<"The "<<n<<"th fabonacci element is: "<<fabinacci(n);
	return 0;
}

時間複雜度為:O(n)

2.3 通向求解



2.4 矩陣乘法 / 分治策略

推導:


#include <cstring>
#include <iostream>

using namespace std;

void MatrixMulti(long long matrix[2][2],long long matrix2[2][2])
{
	long long a = matrix[0][0] * matrix2[0][0] +  matrix[0][1] * matrix2[1][0];
	long long b = matrix[0][0] * matrix2[0][1] +  matrix[0][1] * matrix2[1][1];
	long long c = matrix[1][0] * matrix2[0][0] +  matrix[1][1] * matrix2[1][0];
	long long d = matrix[1][0] * matrix2[0][1] +  matrix[1][1] * matrix2[1][1];
	matrix[0][0] = a;
	matrix[0][1] = b;
	matrix[1][0] = c;
	matrix[1][1] = d;
}

long long fabinacci(int value)
{
	if(value == 0)
	{
		return 0;
	}

	long long A[2][2] = {1,1,1,0};
	long long Matrix[2][2] = {1,0,1,0};

	int n = value - 1;

	for(; n ;n >>= 1)
	{
		//odd
		if(n&1)
		{
			MatrixMulti(Matrix,A);
		}
		MatrixMulti(A,A);
	}

	return Matrix[0][0];
}

int main() 
{
	unsigned int n = 0;
	cout<<"Please input a unsigned integer:"<<endl;
	cin>>n;
	cout<<"The "<<n<<"th fabonacci element is: "<<fabinacci(n);
	return 0;
}

時間複雜度:O(log(N))










相關文章