使用嵌套循环递归的大O复杂性

时间:2014-11-27 12:44:40

标签: java big-o complexity-theory

准备考试我在旧考试中遇到过这个问题:

此函数的最坏情况/大O复杂度是什么:

float foo(float[] A) {
    int n = A.length;
    if (n == 1) return A[0];
    float[] A1 = new float[n/2];
    float[] A2 = new float[n/2];
    float[] A3 = new float[n/2];
    float[] A4 = new float[n/2];

    for (i = 0; i <= (n/2)-1; i++) {
        for (j = 0; j <= (n/2)-1; j++) {
            A1[i] = A[i];
            A2[i] = A[i+j];
            A3[i] = A[n/2+j];
            A4[i] = A[j];
        }
    }

    return foo(A1)
         + foo(A2)
         + foo(A3)
         + foo(A4);
}

(是的,代码没有意义,但这正是它的编写方式)。

让我感到震惊的是,每个递归级别的n的总大小会加倍,但建议的答案(最终结果为O(log n * n^2))会忽略该部分。我误解了什么吗?

编辑:用语法正确(但仍然是荒谬的)代码替换半伪代码。

2 个答案:

答案 0 :(得分:2)

如果你解决了这种递归关系,你就能确定复杂性。

T(n) = 4T(n/2) + O(n²)

使用

T(1) = c

答案 1 :(得分:1)

好的,我终于明白了。

每次我们递归时,我们执行的函数调用次数是上次的4倍,因此如果我们将递归级别定义为m,则每个级别的函数调用次数为

4^m

每次我们递归时,我们也将数组的大小减半,因此每个函数调用的工作量是

(n / 2^m)^2

在每个递归级别,总共完成的工作是:

4^m * (n / 2^m)^2

实际上4^m(2^m)^2相同:

4^m = (2^2)^m = 2^2m = (2^m)^2

因此,工作量可以写成n^2

4^m * (n / 2^m)^2 = (2^m * (n / (2^m))^2 = n^2

log n个递归级别。

因此总工作量为O(n^2 * log n),即,因为有4次递归调用。

如果只有2个递归调用,则每个级别的工作量将为

2^m * (n / 2^m)^2

我们不能很好地减少(但如果我的数学是正确的,那么结果是O(n^2)。)