我们有以下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
的大小还是其他一些方法参数。
一旦确定了输入大小,如何继续确定多次递归的成本?
拜托,您可以告诉我确定成本的递推方程吗?
答案 0 :(得分:1)
调用的原始方法是comb(int[] a, int n)
,您知道a.length <= n
。这意味着您可以使用n
函数限制方法的运行时间,但您应该考虑是否可以使用n
和a.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)
基本上对于给定大小的输入数组,计算答案需要多少步骤?如果您将输入大小加倍,步骤数会发生什么变化?关键是检查你的循环并确定它们被执行的次数。