以下代码的运行时复杂性是什么?

时间:2016-02-22 09:30:37

标签: java time-complexity

以下代码的运行时复杂性

public void foo (int n, int m)
{
   int i = m;
   while (i > 100)
      i = i/3;
   for (int k=i ; k>=0; k--)
   {
      for (int j=1; j<n; j*=2)
         System.out.print(k + "\t" + j);
      System.out.println();
   }
} 

我认为它是O(log n),但我不确定第一个for循环。它最多运行100次,但每次迭代都会记录n。

编辑:这不是How to find time complexity of an algorithm的重复,因为我知道如何找到时间复杂度,但这个具体案例有点棘手所以我只问了这个,我没有问如何找到时间复杂性一般来说。就像我知道如何踢足球这一事实一样,并不意味着我可以像梅西一样踢球,也许我需要一些解释如何做到这一点,但我不需要解释什么是足球等。

4 个答案:

答案 0 :(得分:2)

第一个循环是0(log m),因为迭代给出的值为m / 3,m / 9,m / 27 ......

内循环(在j上)执行其身体日志n次,并且自身最多执行100次

因此复杂度为O(log(m))+ O(log(n))

答案 1 :(得分:0)

让我们先看看第一个循环:

int i = m;
while (i > 100)
   i = i/3;

可以描述为T(i) = O(1) + T(i/3),因为你正在进行一些常量工作(条件比较等),然后用小于三分之一的值重复循环。如果我们通过递归扩展它,我们将得到:

T(i) = O(1) + T(i/3)
     = O(1) + O(1) + T(i/3/3) = 2*O(1) + T(i/9)
     = 2*O(1) + O(1) + T(i/9/3) = 3*O(1) + T(i/27)
     = ... = n*O(1) + T(i/3^n)

最后一个语句是第n次迭代。现在,循环将停止i/3^n <= 100,这意味着何时n = log3(i/100)。因此,您将进行log(i)次操作,这意味着第一个循环的复杂性为O(log(i))。 (请注意,您已设置i = m,因此这基本上是O(log(m)))。

现在让我们看看第二个循环:

for (int k=i ; k>=0; k--) {
   for (int j=1; j<n; j*=2)
      System.out.print(k + "\t" + j);
   System.out.println();
}

内循环可以描述为T(n) = O(1) + T(2*n)。我们来扩展:

T(j) = O(1) + T(2j) = O(1) + O(1) + T(2*2j) = 2*O(1) + T(4j)
     = 2*O(1) + O(1) + T(2*4j) = 3*O(1) + T(8j)
     = ... = l*O(1) + T((2^l)*j)

同样,最后一个是第l次迭代。因此,您将(2^l)*j = n停止一次,这意味着j=log(n)。因此内循环复杂度为O(log(n))

现在让我们看一下外循环。它可以被描述为T(k) = O(log(n)) + T(k-1)。我们来扩展:

T(k) = O(log(n)) + T(k-1) = O(log(n)) + O(log(n)) + T(k-1-1) = 2*O(log(n)) + T(k-2)

到目前为止,我相信你可以通过第l次迭代看到l*O(log(n)) + T(k-l)。您将k-l < 0停留一次k=l,因此复杂度为O(k*log(n))

但是k是什么?好吧,k基本上设置为i的值m被砍掉log3次。因此,您将在log(n)log(m)次工作。因此,您的复杂性为O(log(m)*log(n))

答案 2 :(得分:0)

是的,你把它弄好了O(log(n))+ O(log(m)),它将是O(log(n * m)),因为

  • 第一个循环的复杂性是O(log(m))
  • 第二个循环具有复杂性 of O(log(n))
  • 复杂性~a * log(n)+ b * log(m)
  • min(a,b)(log(n)+ log(m))&lt; a * log(n)+ b * log(m)&lt; max(a,b)(log(n)+ log(m))
  • min(a,b)&lt; [a * log(n)+ b * log(m)] / [(log(n * m))]&lt; max(a,b)

所以你可以说你的表达式是log of log(n * m)

答案 3 :(得分:-1)

由于它包含2个嵌套循环,并且都以log n术语运行,因此

O(log m)= while loop +

O(log m *(log n))= for循环

可以省略日志2和3的基础。

所以它来记录mn(这些中的最大值)