具有多个递归的java方法的开销

时间:2015-12-10 15:15:19

标签: java algorithm recursion asymptotic-complexity recurrence

我们有以下Java方法:

static void comb(int[] a, int i, int max) {
    if(i < 0) {
        for(int h = 0; h < a.length; h++)
            System.out.print((char)(’a’+a[h]));
        System.out.print("\n");
        return;
    }
    for(int v = max; v >= i; v--) {
        a[i] = v;
        comb(a, i-1, v-1);
    }
}

static void comb(int[] a, int n) { // a.length <= n
    comb(a, a.length-1, n - 1);
    return;
}

我必须根据输入的大小确定算法comb(int[],int)的成本的渐近估计。 由于我刚开始使用这种类型的练习,我无法理解在这种情况下输入大小是指数组a的大小还是其他一些方法参数。 一旦确定了输入大小,如何继续确定多次递归的成本?

拜托,您可以告诉我确定成本的递推方程吗?

3 个答案:

答案 0 :(得分:1)

调用的原始方法是comb(int[] a, int n),您知道a.length <= n。这意味着您可以使用n函数限制方法的运行时间,但您应该考虑是否可以使用na.length的函数计算更好的约束。 / p>

例如,如果方法执行a.length * n步骤并且每个步骤花费一定的时间,则可以说该方法需要O(n^2)时间,但O(a.length * n)会更准确(特别是如果n远大于a.length

您应该分析递归调用方法的次数,以及每次调用中发生的操作次数。

答案 1 :(得分:1)

要确定此算法的复杂性,您必须了解您大部分时间花在哪些“工作”上。不同类型的算法可以取决于其参数的不同方面,例如输入大小,输入类型,输入顺序等。这个取决于数组大小和n

System.out.print, (char), 'a' + a [h], a.length, h++等操作是常量时间操作,主要取决于编译后将从执行这些指令的处理器获得的处理器命令。但最终他们可以总结为常数C。此常量不依赖于算法和输入大小,因此您可以安全地从估计中省略它。

此算法线性地依赖于输入大小,因为它循环,它是输入数组(从h = 0到最后一个数组元素的循环)。并且因为n可以等于数组大小(a.length = n - 这是该算法的最坏情况,因为它强制它执行递归“数组大小”次)我们应该在我们的估计中考虑这个输入情况。然后我们得到另一个递归循环,它将执行方法comb其他n次。

因此,在最坏的情况下,我们将获得O(n*n*C)个大量输入大小常量C的执行步骤将变得无关紧要,因此您可以从估算中省略它。因此,最终估算将为O(n^2)

答案 2 :(得分:0)

基本上对于给定大小的输入数组,计算答案需要多少步骤?如果您将输入大小加倍,步骤数会发生什么变化?关键是检查你的循环并确定它们被执行的次数。