解法1:递归
斐波那契数列的标准公式为:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
根据公式可以直接写出:
public static int fibonacci1(int n){ if(n<2){ return n; } else{ return fibonacci1(n-1)+fibonacci1(n-2); } }
时间复杂度:O(2^n) 空间复杂度:O(1)
解法2:动态规划
递归会重复计算大量相同数据,我们用个数组把结果存起来
int Fibonacci(int n) { vector<int> dp(n+1, 0); dp[1] = 1; for (int i=2; i<=n; ++i) { dp[i] = dp[i-1] + dp[i-2]; } return dp[n]; }
解法3:优化存储
优化:发现计算f[5]的时候只用到了f[4]和f[3], 没有用到f[2]...f[0],所以保存f[2]..f[0]是浪费了空间。只需要用3个变量即可
int Fibonacci(int n) { if (n == 0 || n == 1) return n; int a = 0, b = 1, c; for (int i=2; i<=n; ++i) { c = a + b; a = b; b = c; } return c; } 时间复杂度:O(n) 空间复杂度:O(1)
继续优化:两个变量
//非递归的方法 O(N) public static int fibonacci2(int n){ if(n<2){ return n; } int a=0,b=1; for(int i=2;i<=n;i++){ b=b+a;// a=b-a;// } return b; }
时间复杂度:O(n)
空间复杂度:O(1)
解法4:矩阵乘法
f(n) = f(n-1) + f(n-2) f(n-1) = f(n-1) 矩阵: [ f(n) ] = [ 1*f(n-1) + 1*f(n-2) ] = [ 1 1 ] * [ f(n-1) ] [ f(n-1) ] [ 1*f(n-1) + 0*f(n-2) ] [ 1 0 ] [ f(n-2) ] 显然: [ f(2) ] = [ 1 ] [ f(1) ] [ 1 ] 假设: mul = [ 1 1 ] [ 1 0 ] 那么: [f(n) ] = mul * [f(n-1)] = mul*mul*[f(n-2)] = ... = mul^(n-2) * [f(2)] [f(n-1)] [f(n-2)] [f(n-3)] [f(1)]
时间复杂度为O(logn)
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { //给出一个整数 n,请输出斐波那契数列的第 n 项对 1e9 + 7 取模的值。 public static void main(String[] args) throws IOException { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String str = input.readLine(); String[] inputLine = str.split(" "); long m = Long.parseLong(inputLine[0]); System.out.println(fib(m)); } public static long fib(long n) { if (n < 1) { return 0; } if (n < 3) { return 1; } long[][] base = {{1, 1}, {1, 0}}; long[][] res = matrixPower(base, n - 2); return (res[0][0] + res[1][0]) % 1000000007; } public static long[][] matrixPower(long[][] m, long p) { long[][] res = new long[m.length][m[0].length]; for (int i = 0; i < res.length; i++) { res[i][i] = 1; } long[][] tmp = m; while (p != 0) { if ((p & 1) != 0) { res = multMatrix(res, tmp); } tmp = multMatrix(tmp, tmp); p >>= 1; } return res; } private static long[][] multMatrix(long[][] m1, long[][] m2) { long[][] res = new long[m1.length][m2[0].length]; for (int i = 0; i < m1.length; i++) { for (int j = 0; j < m2[0].length; j++) { for (int k = 0; k < m2.length; k++) { res[i][j] += m1[i][k] * m2[k][j]; res[i][j] = res[i][j] % 1000000007; } } } return res; } }