斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), 其中 n > 1.
给定 n,计算 F(n)。
示例 1:
输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1.
示例 2:
输入:3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2.
示例 3:
输入:4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3.
提示:
0 ≤ N ≤ 30
package com.loo;
import java.util.HashMap;
import java.util.Map;
public class Fibonacci {
public static Map<Integer , Integer> map = new HashMap<Integer , Integer>();
public static void main(String[] args) {
int n = 19;
System.out.println(getFibonacci1(n));
System.out.println(getFibonacci2(n));
System.out.println(getFibonacci3(n));
System.out.println(getFibonacci4(n));
System.out.println(getFibonacci5(n));
System.out.println(getFibonacci6(n));
}
// Fn=Fn−1+Fn−2 调用自身,空间复杂度:O(N),时间复杂度:O()
public static int getFibonacci1(int n) {
if (n <= 1) {
return n;
}
return getFibonacci1(n-1) + getFibonacci1(n-2);
}
// 把每次计算结果存起来,时间复杂度:O(N),空间复杂度:O(N)
public static int getFibonacci2(int n) {
if (n <= 1) {
return n;
}
if (map.get(n)!=null) {
return map.get(n);
}
int n1 = getFibonacci2(n-1);
if (map.get(n-1) == null) {
map.put(n-1, n1);
}
int n2 = getFibonacci2(n-2);
if (map.get(n-2) == null) {
map.put(n-2, n2);
}
return n1 + n2;
}
// 叠加前一次计算结果,时间复杂度:O(N),空间复杂度:O(N)
public static int getFibonacci3(int n) {
if (n <= 1) {
return n;
}
int[] cache = new int[n+1];
cache[1] = 1;
for (int i=2;i<=n;i++) {
cache[i] = cache[i-1] + cache[i-2];
}
return cache[n];
}
// 时间复杂度:O(N),空间复杂度:O(1)
public static int getFibonacci4(int n) {
if (n <= 1) {
return n;
}
if (n == 2) {
return 1;
}
int currentValue = 0;
int prevValue1 = 1;
int prevValue2 = 1;
for (int i=3;i<=n;i++) {
currentValue = prevValue1 + prevValue2;
prevValue1 = prevValue2;
prevValue2 = currentValue;
}
return currentValue;
}
// 数学 公式法
public static int getFibonacci5(int n) {
if (n <= 1) {
return n;
}
double k = (1+Math.sqrt(5))/2;
return (int)Math.round(Math.pow(k, n)/Math.sqrt(5));
}
/* 矩阵求幂,时间复杂度:O(logN),空间复杂度:O(logN)
若 n 小于等一 1,则返回 n。
使用递归函数 matrixArr 计算给定矩阵 A 的幂。幂为 n-1,其中 n 是第 n 个 斐波那契数。
matrixArr 函数将对 n/2 个斐波那契数进行操作。
在 matrixArr 中,调用 mutiplyArr 函数将两个矩阵相乘。
完成计算后,返回 A[0][0] 得到第 n 个斐波那契数。
*/
public static int getFibonacci6(int n) {
if (n <= 1) {
return n;
}
int[][] arr = new int[][] {{1 , 1} , {1 , 0}};
matrixArr(arr , n - 1);
return arr[0][0];
}
public static void matrixArr(int[][] A , int n) {
if (n <= 1) {
return;
}
matrixArr(A , n/2);
mutiplyArr(A , A);
int[][] B = new int[][] {{1 , 1} , {1 , 0}};
if ((n & 1) != 0) {
mutiplyArr(A , B);
}
}
public static void mutiplyArr(int[][] A , int[][] B) {
int x = A[0][0] * B[0][0] + A[0][1] * B[1][0];
int y = A[0][0] * B[0][1] + A[0][1] * B[1][1];
int z = A[1][0] * B[0][0] + A[1][1] * B[1][0];
int w = A[1][0] * B[0][1] + A[1][1] * B[1][1];
A[0][0] = x;
A[0][1] = y;
A[1][0] = z;
A[1][1] = w;
}
}