Leetcode题目总结 剑指 Offer 10- I. 斐波那契数列
题目描述
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
做法
1.递推法
注意答案需要取模
可以用滚动数组的思想优化空间到O(1)
2.矩阵快速幂
f(n) = [ 1 1 ] * f(n - 1)
f(n - 1) [ 1 0 ] f(n - 2)
代码
递推法
1 class Solution { 2 public: 3 int fib(int n) { 4 int a[3]; 5 a[0] = 0; 6 a[1] = 1; 7 a[2] = 1; 8 if(n <= 2) return a[n]; 9 for(int i = 3; i <= n; i++) 10 { 11 a[0] = a[1]; 12 a[1] = a[2]; 13 a[2] = (a[0] + a[1]) % (1000000007); 14 } 15 return a[2]; 16 } 17 };
矩阵快速幂
1 class Solution { 2 public: 3 struct matrix { 4 int m[3][3]; 5 }A; 6 matrix mul (matrix A, matrix B) 7 { 8 matrix temp; 9 for(int i = 0; i <= 2; i++) 10 { 11 for(int j = 0; j <= 2; j++) 12 { 13 temp.m[i][j] = 0; 14 } 15 } 16 for(int i = 1; i <= 2; i++) 17 { 18 for(int j = 1; j <= 2; j++) 19 { 20 for(int k = 1; k <= 2; k++) 21 { 22 temp.m[i][j] += A.m[i][k] * B.m[k][j]; 23 } 24 } 25 } 26 return temp; 27 } 28 matrix matrixQuickPow(matrix A, int n) 29 { 30 matrix res,ans; 31 for(int i = 1; i <= 2; i++) 32 { 33 for(int j = 1; j <= 2; j++) 34 { 35 if(i == j) 36 { 37 ans.m[i][j] = 1; 38 } 39 else 40 { 41 ans.m[i][j] = 0; 42 } 43 } 44 } 45 res.m[1][1] = 1; 46 res.m[1][2] = 1; 47 res.m[2][1] = 1; 48 res.m[2][2] = 0; 49 while(n) 50 { 51 if(n & 1) 52 { 53 ans = mul(res,ans); 54 } 55 res = mul(res,res); 56 n = n >> 1; 57 58 } 59 return ans; 60 } 61 int fib(int n) { 62 if(n == 0) return 0; 63 if(n == 1) return 1; 64 A.m[1][1] = 1; 65 A.m[1][2] = 0; 66 matrix temp; 67 n--; 68 temp = matrixQuickPow(A,n); 69 return temp.m[1][1]; 70 } 71 };