我不一定要找答案,但我正在寻找这个问题的要求。发现这个问题正在学习面试,但不确定他们在问什么?
写入贯穿Fibonacci序列并返回的函数 作为参数传入的索引。
答案 0 :(得分:29)
首先,您可以使用wiki中的link更新有关Fibonacci的基础数学信息。并查看this formula进行快速计算。您可以在this link中阅读所有相关内容。
这是计算第n个Fibonacci数的递归函数,且是O(2 ^ n)时间:
int Fibonacci(int n) {
if (n == 0 || n == 1) return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2); }
计算序列
你可能会争辩说,就实际计算的价值而言 在计算机上的斐波那契序列,你最好使用原始 递归关系,f [n] = f [n-1] + f [n-2]。我倾向于同意。使用 对于大n的直接封闭式解决方案,需要维护一个 精确度很高。即使有9位小数, 例如,fn≈round(0.723606798⋅(1.618033989)n)仅对 最多n = 38(观察here与here)。此外,添加整数很多 计算成本更低,更精确,而不是取幂 符号分数或浮点值
这是计算第n个Fibonacci数并且是O(n)时间的更好的想法:
int Fibonacci(int n) {
if(n <= 0) return 0;
if(n > 0 && n < 3) return 1;
int result = 0;
int preOldResult = 1;
int oldResult = 1;
for (int i=2;i<n;i++) {
result = preOldResult + oldResult;
preOldResult = oldResult;
oldResult = result;
}
return result;}
这是计算第n个Fibonacci数的最佳方法,且是O(log(n))时间:
正如您已经怀疑的那样,这将非常相似。使用x * x
矩阵的第n个幂
|1 0 0 0 .... 1 1|
|1
| 1
| 1
| 1
| 1
...................
...................
| ... 1 0|
如果将此矩阵与向量
相乘,这很容易理解f(n-1), f(n-2), ... , f(n-x+1), f(n-x)
导致
f(n), f(n-1), ... , f(n-x+1)
矩阵取幂可以在O(log(n))时间内完成(当x被认为是常数时)。
对于Fibonacci重复,还有一个封闭的公式解决方案,请参阅此处http://en.wikipedia.org/wiki/Fibonacci_number,查找Binet或Moivre公式。
答案 1 :(得分:13)
在我看来,你被要求返回第n个斐波那契号,其中n是传递的参数。您可以使用各种方法来回答这个问题,而所有这些方法在时间复杂度和代码复杂性方面各不相同。
方法1(使用递归) 一种简单的方法,是上面给出的直接recusrive实现数学恢复关系。
int fib(int n)
{
if ( n <= 1 )
return n;
return fib(n-1) + fib(n-2);
}
时间复杂度:T(n)= T(n-1)+ T(n-2)是指数的。 我们可以观察到这个实现做了很多重复的工作(参见下面的递归树)。所以这对于第n个Fibonacci数是一个糟糕的实现。
fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2)fib(1)fib(1)fib(0)fib(1)fib(0) / \ fib(1)fib(0) 额外空间:如果我们考虑fuinction调用堆栈大小,则为O(n),否则为O(1)。
方法2(使用动态编程) 我们可以通过存储到目前为止计算的Fibonacci数来避免重复的工作是方法1。
int fib(int n)
{
/* Declare an array to store fibonacci numbers. */
int f[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
时间复杂度:O(n) 额外空间:O(n)
方法3(空间优化方法2) 我们可以通过存储前两个数字来优化方法2中使用的空间,因为这就是我们需要获得的下一个Fibannaci数字。
int fib(int n)
{
int a = 0, b = 1, c, i;
if( n == 0)
return a;
for (i = 2; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
return b;
}
时间复杂度:O(n) 额外空间:O(1)
方法4(使用matrx {{1,1},{0,1}}的力量) 另一个O(n)依赖于如果我们将矩阵M = {{1,1},{0,1}}乘以其自身(换句话说计算功率(M,n))的事实,那么我们得到第(n + 1)个Fibonacci数作为结果矩阵中行和列(0,0)的元素。
矩阵表示为Fibonacci数字提供以下闭合表达式:
/* Helper function that multiplies 2 matricies F and M of size 2*2, and
puts the multiplication result back to F[][] */
void multiply(int F[2][2], int M[2][2]);
/* Helper function that calculates F[][] raise to the power n and puts the
result in F[][]
Note that this function is desinged only for fib() and won't work as general
power function */
void power(int F[2][2], int n);
int fib(int n)
{
int F[2][2] = {{1,1},{1,0}};
if(n == 0)
return 0;
power(F, n-1);
return F[0][0];
}
void multiply(int F[2][2], int M[2][2])
{
int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
void power(int F[2][2], int n)
{
int i;
int M[2][2] = {{1,1},{1,0}};
// n - 1 times multiply the matrix to {{1,0},{0,1}}
for ( i = 2; i <= n; i++ )
multiply(F, M);
}
时间复杂度:O(n) 额外空间:O(1)
方法5(优化方法4) 可以优化方法4以在O(Logn)时间复杂度中工作。我们可以进行递归乘法以获得流行方法中的幂(M,n)(类似于本文中的优化)
void multiply(int F[2][2], int M[2][2]);
void power(int F[2][2], int n);
/* function that returns nth Fibonacci number */
int fib(int n)
{
int F[2][2] = {{1,1},{1,0}};
if(n == 0)
return 0;
power(F, n-1);
return F[0][0];
}
/* Optimized version of power() in method 4 */
void power(int F[2][2], int n)
{
if( n == 0 || n == 1)
return;
int M[2][2] = {{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if( n%2 != 0 )
multiply(F, M);
}
void multiply(int F[2][2], int M[2][2])
{
int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
时间复杂度:O(Logn) 额外空间:如果我们考虑函数调用堆栈大小,则为O(Logn),否则为O(1)。
驱动程序: int main() { int n = 9; printf(“%d”,fib(9)); 的getchar(); 返回0; }
参考文献: http://en.wikipedia.org/wiki/Fibonacci_number http://www.ics.uci.edu/~eppstein/161/960109.html
答案 2 :(得分:2)
这是一个措辞非常糟糕的问题,但您必须假设他们要求提供{<1>}作为参数的n th Fibonnaci编号。
除了其他人列出的所有技术外,对于n
,您还可以使用golden ratio method,这比任何迭代方法都快。但正如问题所说'贯穿斐波纳契序列',这可能不符合条件。你可能也会吓死他们。
答案 3 :(得分:0)
public static int fibonacci(int i){
if(i==0)
return 0;
if(i==1)
return 1;
return fib(--i,0,1);
}
public static int fib(int num,int pre,int prepre){
if(num==0){
return prepre+pre;
}
return fib(--num,pre+prepre,pre);
}
答案 4 :(得分:0)
我以不同的方式解释问题....假设number
作为输入,该系列中该数字的index
是多少?例如input=5
,然后索引为5
(给定序列为0 1 1 2 3 5
,其中索引以0
开头)
此代码如下(返回索引)[免责声明:改编自http://talkbinary.com/programming/c/fibonacci-in-c/给出的代码]
int Fibonacci(int n)
{
if ( n == 0 )
return 0;
if ( n== 1 )
return 1;
int fib1 = 0;
int fib2 = 1;
int fib = 0;
int i = 0;
for (i = 2; ; i++ )
{
fib = fib1 + fib2;
if ( n == fib )
break;
fib1 = fib2;
fib2 = fib;
}
return i;
}