Fibonacci系列是0 1 1 2 3 5 8 ...依此类推。它可以使用交换元素获得并显示它们,而我们可以使用数组获取它。我被要求使用面试中的递归和主要逻辑来找到它,
int fib(int n){
if(n<1)
return 1;
else
return fib(n-1)+fib(n-2);}
它为大数量产生堆栈问题,因为我们在这里增加了复杂性。那么这里的最佳方式是什么?
答案 0 :(得分:2)
具有讽刺意味的是,上面使用的方法,即 binary recursion (二进制递归)通过在每种非基本情况下进行两次递归调用来计算斐波那契数。不幸的是,以这种方式直接执行斐波那契公式编号需要对该方法进行指数调用。
由于第n个斐波那契数F(n)取决于前两个值F(n-2)和F(n-1)的方式,我们很想使用错误的递归公式。但请注意,在计算F(n-2)之后,对计算F(n-1)的调用需要自己的递归调用来计算F(n-2),因为它不了解F(n- 2)是在较早的递归级别上计算的。那是重复的工作。更糟糕的是,这两个调用都将需要(重新)计算F(n-3)的值,以及F(n-1)的计算。滚雪球效应就是导致fib()
指数运行时间的原因。
我们可以使用线性递归更高效地计算F(n),其中每次调用仅进行一次递归调用。为此,我们需要重新定义该方法的期望。我们没有使用返回单个值(即第n个斐波那契数)的方法,而是定义了一种递归方法,该方法使用约定F()返回具有两个连续斐波那契数{F(n),F(n-1)}的数组。 -1)= 0。虽然报告两个连续的斐波那契数而不是一个报告似乎是一个更大的负担,但是,将这些额外的信息从递归的一个级别传递到下一个递归级别将使继续该过程变得更加容易。 (这使我们避免了必须重新计算递归中已知的第二个值。) 基于此策略的实现是clearly shown here.
答案 1 :(得分:1)
记忆化。创建仅计算每次纤维麻木的逻辑。
static BigInteger[] fibNumbs = new BigInteger[10000];
public static void main(String[] args) {
fibNumbs[1] = BigInteger.ONE;
fibNumbs[2] = BigInteger.ONE;
System.out.println(fibOf(10000));
}
public static BigInteger fibOf(int n) {
if (n <= 1) {
return BigInteger.ONE;
}
if (fibNumbs[n - 1]==null) {
fibNumbs[n - 1] = fibOf(n - 1);
}
if (fibNumbs[n - 2]==null) {
fibNumbs[n - 2] = fibOf(n - 2);
}
return fibNumbs[n - 1].add(fibNumbs[n - 2]);
}
答案 2 :(得分:0)
如果我告诉你两个连续的斐波那契数字,例如。 a=3
和b=5
,您能猜出下一个吗?它是两个求和的8
。现在使用a=5
和新计算的数字b=8
,您可以计算下一个?您使用前两个0
,1
开始迭代,并为您倒计时的每次迭代所需的数字索引以及当您达到零时a
是您的答案。这是一个O(n)算法。