博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)
阅读量:5930 次
发布时间:2019-06-19

本文共 1886 字,大约阅读时间需要 6 分钟。

 
对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - 1) + F(n - 2),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n)。第一个斐波拉契数为F(0) = 1。 给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod 1000000007。

 斐波拉契数列的计算是一个非常经典的问题,对于小规模的n,很容易用递归的方式来获取,对于稍微大一点的n,为了避免递归调用的开销,可以用动态规划的思想轻松获得,时间复杂度为O(n),空间复杂度为O(1). 但是对于更大规模,比如上题中的n的范围,动态规划所花的时间也不少了。好在之前在上碰倒这个问题。

考虑下面三个矩阵:

F(n)   F(n-1)        1,1         F(n-1)  F(n-2)

F(n-1) F(n-1)  与   1,0   与   F(n-2)  F(n-3)

分别设为S(n), M, S(n-1).  S(n) = M x S(n-1).

于是

 S(n) = M^(n-1) x S(1) = M^n;   (关系1)

再来看看,若n为32位正整数,设c[32]为其二进制序列的逆序列, c[i] =0,1;

n = Σ(c[i]*2^i),  i=0,...,31;

所以只要我知道M的2^i 方幂(i=0,1,2,...,31),我们可以轻松计算出S(n)

而计算出32个M的幂需要做32次矩阵乘法,而计算M^n次方,即M^( Σ(c[i]*2^i) ) 也最多需要做32次矩阵乘法

因而最多64次矩阵乘法即可计算出任意32位正整数范围的n对应的S(n)

按 Ctrl+C 复制代码
class Fibonacci { /*author: Haibin Chen*/ public:    int getNthNumber(int n) {        // write code here        if(n <=1) return 1;        long a[32];        long b[32];        long c[32];        long d[32];        a[0]=1;        b[0]=1;        c[0]=1;        d[0]=0;        int i,j;        for(i=1;i<32;i++){            a[i] = a[i-1];            b[i] = b[i-1];            c[i] = c[i-1];            d[i] = d[i-1];            getMulti(a[i],b[i],c[i],d[i],a[i],b[i],c[i],d[i]);        }        long ra = 1,rb =0,rc=0,rd=1,mask=1;        for(i=0;i<32;i++){            if((n&mask)!=0){               getMulti(ra,rb,rc,rd,a[i],b[i],c[i],d[i]);            }            mask = mask <<1;        }        return ra;    }    void getMulti(long &a,long &b,long &c,long &d,long a1,long b1,long c1,long d1){        long tempa = (a*a1+b*c1)%1000000007;        long tempb = (a*b1+b*d1)%1000000007;        long tempc = (c*a1+d*c1)%1000000007;        long tempd = (c*b1+d*d1)%1000000007;        a = tempa;        b = tempb;        c = tempc;        d = tempd;    }};

转载来源:http://www.cnblogs.com/chenhaibin/p/4674703.html

转载于:https://www.cnblogs.com/swfpt/p/6850430.html

你可能感兴趣的文章
核心动画的使用 - 活动指示器
查看>>
Source Insight 常用设置和快捷键大全
查看>>
Linux学习命令汇总九——atd,crontab任务计划调度及facl文件访问控制列表
查看>>
Cacti 0.8.8b 硬盘、网络流量、cpu、内存告警配置
查看>>
解析:外包软件项目团队构建
查看>>
18个程序员才看得懂的段子
查看>>
C# 基础之类的实例化
查看>>
apache启动报错
查看>>
克隆xen虚拟机及常用命令
查看>>
在Linux上录制终端的操作
查看>>
Firebug使用之一--Console Panel
查看>>
Linux的标准输入和输出
查看>>
李天平DbHelperSQL.cs :利用ADO访问数据库。
查看>>
MTBF
查看>>
JSP表格隔行变色
查看>>
Exchange2003OWA加入更改密码选项
查看>>
JS中加载cssText延时
查看>>
Vmware vSphere 5.0系列教程之四 vSphere网络原理及vSwitch简介
查看>>
sendmail在企业网上的应用(上)
查看>>
LeetCode问题6
查看>>