包含条件的代码的时间复杂度

时间:2017-12-15 17:01:32

标签: algorithm time-complexity

foo(int n)
{
   int s=0;
   for(int i=1;i<=n;i++)
     for(int j=1;j<=i*i;j++)
        if(j%i==0)
          for(k=1;k<=j;k++)
            s++;
}

上述代码的时间复杂度是多少?

我把它作为O(n ^ 5),但它不正确。

2 个答案:

答案 0 :(得分:2)

复杂性为O(n^4)

对于每个i,最内层循环将执行i次。 (ii的倍数0..i*i

它将像内循环一样运行

j = 0 1 2...i i+1 ...2*i ....3*i .... 4*i .... 5*i... i*i
            x         x       x        x        x      x
    \------/\--------/\-------/                 \------/

这些x表示执行具有复杂性j的最内层for循环。其余的时间没有触及,只是测试完成而且失败了。

现在检查一下,这些\-----/i*j (j = 1,2,3...i)循环和i检查。

现在我们准确地i次。

So total work = i*(1+1+1+...1) + i*(1+2+3+..i)
              = i*i+ i*i*(i+1)/2 ~ i^3

使用外部循环,它将是n^4

现在它是什么意思。整个工作可以像这样划分

O(i*j+i)
  ^^^ ^
   |   The other cases when it simply skips
  The innermost loop executed

现在,如果我们迭代j,那么它将具有复杂性O(n^3)

添加外部循环后,它将为O(n^4)

答案 1 :(得分:1)

您的函数计算四维金字塔数(A001296)。可以使用以下公式计算s的增量数:

a(n) = n*(1+n)*(2+n)*(1+3*n)/24

因此,函数的复杂性为O(n 4 )。

它不是O(n 5 )的原因是if (j%i == 0)只对i的倍数进行“有效载荷”循环,其中我们有i {在j到i 2 范围内的所有1中{1}}。

因此,我们为最外层循环添加一个,为中间循环添加一个,为最内层循环添加两个,因为它迭代到i 2 ,总共4个。 / p>

  

为什么只有一个中间(j)?它运行到i 2 对吗?

也许更容易看出我们是否重写代码以排除条件:

int s=0;
for(int i=1;i<=n;i++)
    for(int j=1;j<=i;j++)
        for(int k=1;k<=i*j;k++)
            s++;
return s;

此代码生成相同数量的“有效负载循环”迭代,但不是“过滤掉”跳过内部循环的迭代,而是通过计算最内层循环中k的终值来将它们从考虑中删除为i*j