时间复杂度为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;
}
};
}; |