答案 0 :(得分:18)
如果你对内存有限制,你可以简单地使用函数的尾递归版本来返回最后两个斐波那契数字。
int fib(int n)
{
int a = 0;
int b = 1;
while (n-- > 1) {
int t = a;
a = b;
b += t;
}
return b;
}
这是O(n)
,需要一个恒定的空间。
答案 1 :(得分:14)
答案 2 :(得分:12)
答案 3 :(得分:10)
答案 4 :(得分:7)
答案 5 :(得分:6)
答案 6 :(得分:4)
没人提到2值堆栈数组版本,所以我只是为了完整性而做。
// do not call with i == 0
uint64_t Fibonacci(uint64_t i)
{
// we'll only use two values on stack,
// initialized with F(1) and F(2)
uint64_t a[2] = {1, 1};
// We do not enter loop if initial i was 1 or 2
while (i-- > 2)
// A bitwise AND allows switching the storing of the new value
// from index 0 to index 1.
a[i & 1] = a[0] + a[1];
// since the last value of i was 0 (decrementing i),
// the return value is always in a[0 & 1] => a[0].
return a[0];
}
这是一个O(n)常量堆栈空间解决方案,在使用优化进行编译时,其执行方式与memoization略有相同。
// Calc of fibonacci f(99), gcc -O2
Benchmark Time(ns) CPU(ns) Iterations
BM_2stack/99 2 2 416666667
BM_memoization/99 2 2 318181818
此处使用的BM_memoization只会初始化一次数组,并在每次其他调用时重复使用它。
2值堆栈数组版本在优化时与具有临时变量的版本完全相同。
答案 7 :(得分:3)
您还可以使用快速倍增法生成斐波那契系列 链接 - http://vinayakgarg.wordpress.com/2012/11/07/fastest-way-to-compute-fibonacci-number/
它实际上是从矩阵求幂方法的结果中得出的。
答案 8 :(得分:2)
答案 9 :(得分:1)
答案 10 :(得分:1)
在C#中:
static int fib(int n)
{
if (n < 2) return n;
if (n == 2) return 1;
int k = n / 2;
int a = fib(k + 1);
int b = fib(k);
if (n % 2 == 1)
return a * a + b * b;
else
return b * (2 * a - b);
}
答案 11 :(得分:1)
矩阵乘法,无浮点算术, O(log N)时间复杂度假设整数乘法/加法是在恒定时间内完成的。
这里是python代码
def fib(n):
x,y = 1,1
mat = [1,1,1,0]
n -= 1
while n>0:
if n&1==1:
x,y = x*mat[0]+y*mat[1], x*mat[2]+y*mat[3]
n >>= 1
mat[0], mat[1], mat[2], mat[3] = mat[0]*mat[0]+mat[1]*mat[2], mat[0]*mat[1]+mat[1]*mat[3], mat[0]*mat[2]+mat[2]*mat[3], mat[1]*mat[2]+mat[3]*mat[3]
return x
答案 12 :(得分:1)
答案 13 :(得分:1)
答案 14 :(得分:0)
答案 15 :(得分:0)
在函数式编程中,有一种计算斐波纳契的特殊算法。该算法使用累积递归。累积递归用于最小化算法使用的堆栈大小。我认为它可以帮助您减少时间。如果你愿意,你可以试试。
int ackFib (int n, int m, int count){
if (count == 0)
return m;
else
return ackFib(n+m, n, count-1);
}
int fib(int n)
{
return ackFib (0, 1, n+1);
}
答案 16 :(得分:0)
使用以下任何一个:递归的两个例子,一个用于循环O(n)时间,一个用黄金比率O(1)时间:
private static long fibonacciWithLoop(int input) {
long prev = 0, curr = 1, next = 0;
for(int i = 1; i < input; i++){
next = curr + prev;
prev = curr;
curr = next;
}
return curr;
}
public static long fibonacciGoldenRatio(int input) {
double termA = Math.pow(((1 + Math.sqrt(5))/2), input);
double termB = Math.pow(((1 - Math.sqrt(5))/2), input);
double factor = 1/Math.sqrt(5);
return Math.round(factor * (termA - termB));
}
public static long fibonacciRecursive(int input) {
if (input <= 1) return input;
return fibonacciRecursive(input - 1) + fibonacciRecursive(input - 2);
}
public static long fibonacciRecursiveImproved(int input) {
if (input == 0) return 0;
if (input == 1) return 1;
if (input == 2) return 1;
if (input >= 93) throw new RuntimeException("Input out of bounds");
// n is odd
if (input % 2 != 0) {
long a = fibonacciRecursiveImproved((input+1)/2);
long b = fibonacciRecursiveImproved((input-1)/2);
return a*a + b*b;
}
// n is even
long a = fibonacciRecursiveImproved(input/2 + 1);
long b = fibonacciRecursiveImproved(input/2 - 1);
return a*a - b*b;
}
答案 17 :(得分:0)
答案 18 :(得分:0)
答案 19 :(得分:0)
答案 20 :(得分:0)
using namespace std;
void mult(LL A[ 3 ][ 3 ], LL B[ 3 ][ 3 ]) {
int i,
j,
z;
LL C[ 3 ][ 3 ];
memset(C, 0, sizeof( C ));
for(i = 1; i <= N; i++)
for(j = 1; j <= N; j++) {
for(z = 1; z <= N; z++)
C[ i ][ j ] = (C[ i ][ j ] + A[ i ][ z ] * B[ z ][ j ] % mod ) % mod;
}
memcpy(A, C, sizeof(C));
};
void readAndsolve() {
int i;
LL k;
ifstream I(FIN);
ofstream O(FOUT);
I>>k;
LL A[3][3];
LL B[3][3];
A[1][1] = 1; A[1][2] = 0;
A[2][1] = 0; A[2][2] = 1;
B[1][1] = 0; B[1][2] = 1;
B[2][1] = 1; B[2][2] = 1;
for(i = 0; ((1<<i) <= k); i++) {
if( k & (1<<i) ) mult(A, B);
mult(B, B);
}
O<<A[2][1];
}
//1,1,2,3,5,8,13,21,33,...
int main() {
readAndsolve();
return(0);
}
答案 21 :(得分:0)
public static int GetNthFibonacci(int n)
{
var previous = -1;
var current = 1;
int element = 0;
while (1 <= n--)
{
element = previous + current;
previous = current;
current = element;
}
return element;
}
答案 22 :(得分:0)
这类似于之前给出的答案,但有一些修改。如其他答案中所述,记忆是另一种方法,但我不喜欢随着技术变化而缩放的代码(unsigned int
的大小因平台而异)所以最高的值可以达到的顺序也可能不同,我认为记忆是丑陋的。
#include <iostream>
using namespace std;
void fibonacci(unsigned int count) {
unsigned int x=0,y=1,z=0;
while(count--!=0) {
cout << x << endl; // you can put x in an array or whatever
z = x;
x = y;
y += z;
}
}
int main() {
fibonacci(48);// 48 values in the sequence is the maximum for a 32-bit unsigend int
return 0;
}
此外,如果使用<limits>
可以编写一个编译时常量表达式,它将为您提供序列中可以达到的任何整数数据类型的最大索引。
答案 23 :(得分:-1)
#include<stdio.h>
main()
{
int a,b=2,c=5,d;
printf("%d %d ");
do
{
d=b+c;
b=c;
c=d;
rintf("%d ");
}