时间复杂度为O( log n )的方法:

该算法使用矩阵乘法操作,使得算法时间复杂度为 O(logN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
long long Fibonacci( unsigned n )   
{   
      int result[2] = {0, 1};   
      if(n < 2)   
            return result[n];   
 
      long long   fibOne = 0;   
      long long   fibTwo = 1;   
      long long   fibThree ;   
     
      for(unsigned int i = 2; i <= n; ++ i)   
       {   
             fibThree = fibOne + fibTwo;   
      fibOne = fibTwo ;   
             fibNTwo = fibThree;   
        }   
        return fibThree;   
}
  
 
/*
下面介绍一种时间复杂度是O(logn)的方法:
 
对于斐波那契数列1,1,2,3,5,8,13…….有如下定义:
 
F( n ) = F( n-1 ) + F( n-2 )
F( 1 ) = 1
F( 2 ) = 1
 
矩阵形式:
 
[ F( n+1 ) ,  F( n ) ] = [ F( n ) , F( n-1 ) ] * Q  其中 [ F( n+1 ) ,  F( n ) ]为行向量,Q = { [ 1, 1 ]; [ 1, 0 ] }为矩阵
 
则 [ F( n+1 ) , F( n ) ]=[ 1 , 0 ] * Qn , 
*/struct Matrix    
{          
       long long m_00, m_01, m_10, m_11;   
   Matrix ( long long m00 = 0,  long long m01 = 0,  long long m10 = 0,   long long m11 = 0 )    
       :m_00( m00 ), m_01( m01 ), m_10( m10 ), m_11( m11 )     
       {    
       }    
};
  
 
Matrix MatrixMultiply (  const Matrix & m1, const Matrix & m2    )    
{  
  long long m00 = m1.m_00 * m2.m_00 + m1.m_01 * m2.m_10;
  long long m01 = m1.m_00 * m2.m_01 + m1.m_01 * m2.m_11; 
  long long m10 = m1.m_10 * m2.m_00 + m1.m_11 * m2.m_10    
  long long m11 = m1.m_10 * m2.m_01 + m1.m_11 * m2.m_11; 
      return Matrix ( m00,  m01,  m10, m11 );    
}
 
Matrix MatrixPower( unsigned int n )    
{    
       assert(n > 0);    
       Matrix m;    
       if( n == 1)    
       {    
             m = Matrix(1, 1, 1, 0);    
       }    
      else if(n % 2 == 0)    
       {    
             m = MatrixPower( n / 2 );    
             m = MatrixMultiply( matrix, matrix );    
       }    
      else if( n % 2 == 1 )    
       {    
             m = MatrixPower( (n - 1) / 2 );    
             m = MatrixMultiply( m, m );    
             m = MatrixMultiply( m, Matrix( 1, 1, 1, 0 ) );    
       }     
      return m;    
}  
long long Fibonacci( unsigned int n )
{
      int result[2] = { 0, 1 };
      if( n < 2 )
            return result[ n ];
 
      Matrix Q = MatrixPower( n - 1 );  //注意:按定义式应该用[ 1, 0 ]*Q, 或者等价于{ [ 1 , 0 ]; [ 0, 0 ] }*Q, 但是因为显然结果相同,所以略去这一步。return Q.m_00;
}


牛客网答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Solution {
public:
    int Fibonacci(int n) {
        int result[2]={0,1};
        if(n<2)return result[n];
        Matrix m;
        return m.Power(n-1).a00;
    }
    class Matrix{
          
    public:
        long int a00;
        long int a01;
        long int a10;
        long int a11;
        Matrix (long int a,long int b,long int c,long int d){
            a00=a;
            a01=b;
            a10=c;
            a11=d;
        }
        Matrix (){
            a00=1;a01=1;a10=1;a11=0;
        }
        Matrix operator * (Matrix & m2){
            long int b00 = a00 * m2.a00 + a01 * m2.a10;
            long int b01 = a00 * m2.a01 + a01 * m2.a11;
            long int b10 = a10 * m2.a00 + a11 * m2.a10;   
            long int b11 = a10 * m2.a01 + a11 * m2.a11;
            return Matrix(b00,b01,b10,b11);
        }
        Matrix Power( unsigned int n )   
        {   
               Matrix m;   
               if( n == 1)   
               {   
                     m = Matrix(1, 1, 1, 0);   
               }   
              else if(n % 2 == 0)   
               {   
                     m = Power( n / 2 );   
                     m = m*m;   
               }   
              else if( n % 2 == 1 )   
               {   
                     m = Power( (n - 1) / 2 );   
                     m = m*m; 
                     Matrix tmp;
                     m = m*tmp ;   
               }    
              return m;   
        
       };     
};

Fibonacci 数列第 N项 O(logN)算法的更多相关文章

  1. Fibonacci数列前n项值的输出(运用递归算法)

    1.斐波那契数列: 又称黄金分割数列,指的是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 在数学上,斐波纳契数列以如下被以递归的方法 ...

  2. Problem D: 调用函数,输出Fibonacci数列的m项至n项

    #include<stdio.h> int fib(int n)//定义FIbonacci函数 { int s,i; ||n==) { s=; } else { int s1,s2; s1 ...

  3. c语言经典算法---计算Fibonacci数列

    算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手.下面我就分享一个C语言中比较基础却极为重要的一个算法----计算Fi ...

  4. 程序员面试题精选100题(16)-O(logn)求Fibonacci数列[算法]

    作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:定义Fibonacci数列如下: /  0                      n=0 f(n)=      ...

  5. 【编程题目】题目:定义 Fibonacci 数列 输入 n,用最快的方法求该数列的第 n 项。

    第 19 题(数组.递归):题目:定义 Fibonacci 数列如下:/ 0 n=0f(n)= 1 n=1/ f(n-1)+f(n-2) n=2输入 n,用最快的方法求该数列的第 n 项. 思路:递归 ...

  6. Fibonacci 数列O(logn)解法

    传统解法 提到斐波那契数列(Fibonacci Sequence),首先想到的是经典的动规(DP)算法. 时间复杂度O(n),这里空间复杂度可以优化到O(1).代码如下: int fib_n(int ...

  7. wikioi 1973 Fibonacci数列【输出第N项的值】

    /*===================================== 1978 Fibonacci数列 3 题目描述 Description 斐波纳契数列是这样的数列: f1 = 1 f2 ...

  8. 递归函数练习:输出菲波拉契(Fibonacci)数列的前N项数据

    /*====================================================================== 著名的菲波拉契(Fibonacci)数列,其第一项为0 ...

  9. 《面试题精选》15.O(logn)求Fibonacci数列

    题目:定义Fibonacci数列例如以下: /    0                      n=0 f(n)=      1                      n=1          ...

随机推荐

  1. mybatis 主键UUID生成策略

    <insert id="insert" parameterType="com.lsfwpt.lawmis.po.SysUser"> <sele ...

  2. 常用的HTTP状态码如下

    成功的状态码: – 服务器成功返回网页 – 未修改 失败的状态码: – 请求的网页不存在 – 服务器暂时不可用 – 服务器内部错误 下面的不是很常用,记住上面那几个就ok了,有bug了再补充 其他的状 ...

  3. Java Object 构造方法的执行顺序

    Java Object 构造方法的执行顺序 @author ixenos 为了使用类而做的准备工作包括三个步骤 1)加载:类加载器查找字节码(一般在classpath中找),从字节码创建一个Class ...

  4. Java JVM 多态(动态绑定)

    Java JVM 多态(动态绑定) @author ixenos 摘要:绑定.动态绑定实现多态.多态的缺陷.纯继承与扩展接口.向下转型与RTTI 绑定 将一个方法的调用和一个方法的主体关联起来,称作( ...

  5. 2016弱校联盟十一专场10.2——Floyd-Warshall

    题目链接:Floyd-Warshall 题意: 给你n个点,m条边,100>m-n>0,现在有q个询问,问你任意两点的最短距离,题目保证每条边都被连接,每条边的距离为1 题解: 首先我们可 ...

  6. 8.Hibernate的多对多关联映射

    1.创建如下数据库脚本 --1.1 项目表 create table PROJECT ( proid ) not null, proname ) ) ; --1.2 项目表主键 alter table ...

  7. Iphone CPU 架构类型

    armv6设备:iPhone, iPhone2, iPhone 3G,第一代.第二代iPod Touch armv7设备:iPhone 3GS, iPhone 4, iPhone 4S iPad , ...

  8. 正方形网格 TRIANGLE_STRIP连接

    unsigned int vIdx = 0, iIdx = 0; for (unsigned int stripRow = 0; stripRow < stripRows; stripRow++ ...

  9. Python库 - import matplotlib.pyplot as plt 报错问题

    为了避免各种问题,请使用最新的2.7.13安装文件   1.先设置好环境变量 在path变量中设置好以下路径: C:\Python27\Scripts C:\Python27    2.大部分报错问题 ...

  10. digitalocean优惠码30美元1G内存VPS免费使用两个月

    著名的云主机服务商CloudWays送福利啦!CloudWays是一家云主机网站服务商,与Digitalocean和亚马逊AWS开展合作,新用户注册验证手机即可赠送价值30美元的免费VPS主机. 申请 ...