[英]How would I find the time-complexity of a recursive method in Java?
我无法完全掌握复杂性的概念,我想知道如何在这段代码中为方法f(n)计算它:
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random();
r.setSeed(System.currentTimeMillis());
int n = r.nextInt(20) + 1;
f(n);
}
private static void f(int n){
if(n > 0){
g(n);
System.out.println();
f(n-1);
}
}
private static void g(int n){
if(n > 0){
System.out.print('X');
g(n-1);
}
}
}
我知道这是一种递归方法,令我感到困惑。 我看到每次调用函数f()时,都会调用g()并运行n次,然后f()再次将自身称为n-1,直到n = 0。 我不知道从哪里开始任何帮助都会很棒。 谢谢。
确定递归函数的运行时间的常用技术是写出将运行时描述为根据其自身定义的数量的递归关系 。 让我们从g开始。 如果我们让c n表示g(n)的运行时间,那么我们就有了
我们可以查看几个值来查看我们是否发现了一个模式:
一般来说,它看起来像c n = n + 1.如果你愿意的话,可以通过归纳证明来形式化这个,但是现在我们要坚信。 这意味着g的运行时间是O(n)。
现在,让我们让d n成为调用f(n)的运行时。 请注意
我们可以扩展它,看看我们是否看到了一种模式。
通常,它看起来像d n = n +(n-1)+(n-2)+ ... + 1.如果您愿意,可以通过归纳将其形式化。 这是一个着名的和,它可以达到n(n + 1)/ 2.这个数量碰巧是Θ(n 2 ),所以整个运行时间是Θ(n 2 )。
首先,计算g()作为传递给f()的初始参数n的函数的次数。 这将为您提供函数所花费的时间量,作为执行g()所需时间的倍数,不包括递归。
然后丢弃系数和低阶项。 例如,如果你的结果是0.5n ^ 2 + 0.5n,你会下降0.5n,因为它是一个较低阶项 - 不是平方 - 留下0.5n ^ 2,你会丢弃0.5系数,留下n ^ 2 。 这意味着该函数在O(n ^ 2)时间内运行。
虽然不是分析递归的一般策略,但是对于跨越1到n的k
值,你的f(n)
本质上是一个运行g(k)
的循环。 因此, f(n)
的运行时间基本上是g(n)
, g(n-1)
,..., g(2)
, g(1)
的运行时间的总和。
由于您已经知道g(k)
的运行时间本质上是k
,因此您的最终运行时间是从1到n的总和。 如果你知道你的求和公式,你就会知道它的顺序是O(n 2 )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.