每日一题--生成斐波那契数列的三种方法(递归、非递归、矩阵)(Google推荐面试书--Cracking the Coding Interview)

题目

  • 原文:
    Write a method to generate the nth Fibonacci number.
  • 译文:
    写一个函数来产生第n个斐波那契数。

分析
斐波那契数列想必大家都很熟悉啦,递归方法和非递归方法很常规,这里就不详细介绍了,代码详见fib1()和fib2()。
今天主要来介绍下一种新鲜学到的矩阵算法,以及其中用到的做幂运算的速度更快的方式:
在这里插入图片描述
此时fn就等于矩阵的(n-2)次方后矩阵中第一行两列数相加。
在做m^n这样的幂运算时,常规方法我们是这样的:

ll pow(ll m, ll n){
    ll res = 1;
    for(ll i=0; i<n; ++i)
        res *= m;
    return res;
}

这样的时间复杂度为O(n),而下面这种利用位运算的方法则可以把速度提升到O(logn):

ll pow1(ll m, ll n){
    ll res = 1;
    while(n > 0){
        if(n&1) res *= m;
        m *= m;
        n >>= 1;
    }
    return res;
}

这是什么原理呢?
一个十进制的数字总是可以以二进制的方式表示,比如11写成二进制就是1011,即8+2+1。那么m^11就可以写成m的(1+2+8)次方,也即m的1次方乘上m的2次方乘上m的8次方。这样就把11这个数字依次右移与1做按位与运算,如果对应位为1就乘以相应的m的相应次方。
整数求幂如此,矩阵亦然,具体见代码fib3()。

代码

#include<iostream>
using namespace std;

typedef long long ll;

//recursion version
ll fib1(int n) {
	if(n <= 0) {
		return 0;
	}
	else if(n == 1 || n == 2) {
		return 1;
	}
	else {
		return fib1(n-1) + fib1(n-2);
	}
}

//unrecursion version
ll fib2(int n) {
	if(n <= 0) {
		return 0;
	}
	else if(n == 1 || n == 2) {
		return 1;
	}
	else {
		ll a = 1, b = 1;
		while(n-- > 2) {
			ll c = a + b;
			a = b;
			b = c;
		}
		return b;
	}
}

mul(ll c[2][2], ll b[2][2], ll a[2][2]) {
	ll t[4];
	t[0] = b[0][0] * a[0][0] + b[0][1] * a[1][0];
	t[1] = b[0][0] * a[0][1] + b[0][1] * a[1][1];
	t[2] = b[1][0] * a[0][0] + b[1][1] * a[1][0];
	t[3] = b[1][0] * a[0][1] + b[1][1] * a[1][1];
	c[0][0] = t[0];
	c[0][1] = t[1];
	c[1][0] = t[2];
	c[1][1] = t[3];	
}

pow(ll b[2][2], ll a[2][2], int n){
	while(n > 0) {
		if(n & 1) {
			mul(b, b, a);
		}
		mul(a, a, a);
		n >>= 1;
	}
}

//matrix version
ll fib3(int n) {
	if(n <= 0) {
		return 0;
	}
	else if(n == 1 || n == 2) {
		return 1;
	}
	else {
		ll a[2][2] = {{1,1}, {1,0}};
		ll b[2][2] = {{1,1}, {1,0}};
		pow(b, a, n-3);
		return b[0][0] + b[0][1];
	}
} 

int main() {
	ll a = fib1(5);
	ll b = fib2(5);
	ll c = fib3(5);
	cout << a << " " << b << " " << c;
}

输出结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_39860046/article/details/88092636
今日推荐