如何在Java中找到递归方法的时间复杂性?
我还没有完全掌握复杂性的概念,我想知道我如何才能计算出这段代码中方法f(n)的复杂性:如何在Java中找到递归方法的时间复杂性?,java,recursion,big-o,time-complexity,Java,Recursion,Big O,Time Complexity,我还没有完全掌握复杂性的概念,我想知道我如何才能计算出这段代码中方法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); }
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开始。如果让cn表示g(n)的运行时,那么
- c0=1(调用g(0)需要恒定的工作量)
- cn+1=cn+1(调用g(n)自己做恒定量的工作,然后调用g(n-1)
- c0=1
- c1=c0+1=1+1=2
- c2=c1+1=2+1=3
- c3=c2+1=3+1=4
- d0=1(调用f(0)会执行恒定的工作量)
- dn+1=dn+cn+1(调用f(n+1)调用g(n+1),需要cn+1工作,然后调用f(n)
- d0=1
- d1=c1+d0=2+1
- d2=c2+d1=3+2+1
- d3=c3+d2=4+3+2+1
一般来说,它看起来像dn=n+(n-1)+(n-2)+…+1。如果你愿意的话,可以通过归纳法将其形式化。这是一个著名的总和,结果是n(n+1)/2。这个量恰好是Θ(n2),所以整个运行时是Θ(n2)。首先,计算调用g()的次数,作为传递给f()的初始参数n的函数。这将为您提供函数所用的时间,即执行g()所用时间的倍数,不包括递归
然后删除系数和低阶项。例如,如果结果为0.5n^2+0.5n,则删除0.5n,因为它是低阶项-不是平方项-留下0.5n^2,然后删除0.5系数,留下n^2。这意味着函数在O(n^2)中运行时间。虽然不是分析递归的一般策略,但您的
f(n)
本质上是一个循环,运行g(k)
的k
值跨越1到n。因此f(n)
的运行时间本质上是g(n)
,g(n-1)
,…,g(2)
,g(1)的运行时间的总和
因为您已经知道g(k)
的运行时间本质上是k
,所以您的最终运行时间是从1到n的总和。如果您知道总和公式,您将知道其顺序是O(n2)