java - 我正在使用斐波那契数,其中第 n 个数的“n”为 5-6 位。我怎样才能减少执行所需的时间?
问题描述
在这个特定的问题中,我要做的是找到斐波那契数,将它们平方,然后找到这些平方数的总和。在长数据类型的范围限制之前,这很好。
这是我到目前为止所拥有的......在注意到 long 的范围无法处理大的斐波那契数之后,我切换到 BigInteger,这起到了作用,但时间复杂度呈指数增长。因为我需要保留大部分数字,所以我需要为这些数字创建一个数组来存储它们。
import java.util.*;
import java.math.*;
public class FibonacciSumSquares {
private static BigInteger getFibonacciSumSquares(int n) {
if (n <= 1)
return BigInteger.valueOf(n);
BigInteger sum = BigInteger.valueOf(0);
BigInteger a[] = new BigInteger[n];
a[0] = a[1] = BigInteger.ONE;
for (int i = 2; i < n; i++) {
a[i] = a[i - 1].add(a[i - 2]);
a[i] = a[i].pow(2);
sum = sum.add(a[i]);
}
return sum;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println(getFibonacciSumSquares(n));
}
}
接受第一个答案后,我对代码片段进行了一些压力测试,所需的更正是代码中的“=”符号。希望有帮助。有关更多详细信息,请参阅答案的评论。
解决方案
BigInteger 的运行速度比 java 原始类型慢,所以在长距离范围内使用原始类型。这是我的代码和结果:
public class FibonacciSumSquares {
private static BigInteger getFibonacciSumSquares(int n) {
if (n <= 1)
return BigInteger.valueOf(n);
BigInteger sum = BigInteger.ZERO;
long last = 1, lastTwo = 1, current = 0;
BigInteger lastBigInteger = BigInteger.ONE;
BigInteger lastTwoBigInteger = BigInteger.ONE;
BigInteger currentBigInteger;
boolean isUsePrimary = true;
for (int i = 2; i <= n; i++) {
if (isUsePrimary) {
current = last + lastTwo;
current = current * current;
if (current > (last + lastTwo)) {
lastTwo = last;
last = current;
sum = sum.add(BigInteger.valueOf(current));
} else {
isUsePrimary = false;
lastTwoBigInteger = BigInteger.valueOf(lastTwo);
lastBigInteger = BigInteger.valueOf(last);
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
} else {
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
}
return sum;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(getFibonacciSumSquares(10000));
System.out.println("used time(ms): " + (System.currentTimeMillis() - start));
/**
* On: MacBook Pro (Retina, 15-inch, Mid 2014)
*
* n = 10000
* 811453295998950457153326378602357232029212
* used time(ms): 24
*
* n = 20000
* 1623556274380606238932066737816445867589212
* used time(ms): 32
*
* n = 999999
* 81209566945485034687670444066761210743605656
* used time(ms): 368
*/
}
}
推荐阅读
- java - 在 JOOQ 中将数据从 RDS 写入磁盘
- css - 在 sass 中正确记录 h1...h6
- mongodb - mongodb查询根据嵌套数据查找数据
- linux - Linux 命名管道 - MKFIFO 查询
- java - 春季用jsp记录页面
- python - 我应该在定义函数的模块中还是在 Python 中调用函数的模块中定义 try-except ?
- java - 我想取出 JAVA 中 BigInteger 中存储的大数的最后一位
- javascript - 如果数据属性匹配 jQuery,则隐藏 div
- angularjs - Angular 更新 ng-model 不带引号
- openweathermap - 只获取白天和黑夜的天气预报