以下代码的运行时复杂性
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。
答案 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)),因为
所以你可以说你的表达式是log of log(n * m)
答案 3 :(得分:-1)
由于它包含2个嵌套循环,并且都以log n术语运行,因此
O(log m)= while loop +
O(log m *(log n))= for循环
可以省略日志2和3的基础。
所以它来记录mn(这些中的最大值)