递归和迭代的fib函数的大订单?

时间:2011-05-11 01:23:07

标签: java algorithm big-o

我被要求以最有效的方式写一个fib函数?

这是我提供的实施:

public static int fib(int n)
{
    int prev1 = 1, prev2 = 1, ans = 1, i = 3;

    while (i <= n)
    {
        ans = prev1 + prev2;
        prev1 = prev2;
        prev2 = ans;
        i++;
    }
    return ans;
}

这是最有效的吗?什么是大订单?

我还被要求给出递归实现的大概念:

public static int recursiveFib(int n)
{
    if (n <= 2)
        return 1;
    else
        return recursiveFib(n-1) + recursiveFib(n - 2);
}

我认为这个是指数2 ^ n,这就是它效率低下的原因。

3 个答案:

答案 0 :(得分:8)

您的实现是O(n),是实现Fibonacci函数的常规方法。除非使用了memoization或类似的,否则递归定义为O(fib(n))

还有Closed form expression斐波纳契数,This link有一些更快的fib函数实现。

答案 1 :(得分:3)

我想说找到特定n的fib的最佳方法是使用Link中给出的矩阵计算方法 - Page 19

enter image description here

其中F0 = 0且F1 = 1.这种矩阵关系可以很容易地用于找到任何n和n + 1值的fib。最好的部分是乘法矩阵不需要多次n次,而只需logN次以找到乘数的实际值。因此,算法的整体完整性仅为O(logN)。

该等式源自

的基本关系

F1 = 0 * F0 + 1 * F1

F1 = 1 * F0 + 1 * F2

迭代n乘数矩阵必须乘以n次。

答案 2 :(得分:2)

以下是完成此页面的矩阵方法:

public static void main(String[] args)
{
    int n = 25;
    matMul(n - 1);
    System.out.printf("\n%dth Fibonnacci number : %d\n\n", n, M[0][0]);
}

static int[][] M = {{1,0},{0,1}};
static int[][] A = {{1,1},{1,0}};
static int[][] C = {{0,0},{0,0}};

static void matMul(int n)
{
    if (n > 1)
    {
        matMul(n/2);
        mulM(0);
    }
    if (n%2!=0)
    {
        mulM(1);
    }
}

static void mulM(int m)
{
    int i,j,k;

    if (m==0)
    {
        for (i=0;i<2;i++)
            for (j=0;j<2;j++)
            {
                C[i][j]=0;
                for (k=0;k<2;k++)
                    C[i][j]+=M[i][k]*M[k][j];
            }
    }
    else
    {
        for (i=0;i<2;i++)
            for (j=0;j<2;j++)
            {
                C[i][j]=0;
                for (k=0;k<2;k++)
                    C[i][j]+=A[i][k]*M[k][j];
            }
    }
    for (i=0;i<2;i++)
            for (j=0;j<2;j++)
            {
                M[i][j]=C[i][j];
            }
}