嵌套循环的时间复杂度?

时间:2018-03-07 10:43:35

标签: time-complexity

A)

sum = 0;
for(i=1;i<2*n;i++)
 for(j=1;j<i*i;j++)
  for(k=1;k<j;k++)
   if (j % i == 1)
   sum++;

b)中

sum = 0;
for(i=1;i<2*n;i++)
 for(j=1;j<i*i;j++)
  for(k=1;k<j;k++)
   if (j % i)
   sum++;

我在寻找算法分析问题时偶然发现了上面的两个伪代码。上述两个片段的答案分别为O(n 4 )和O(n 5 )。

请注意,此处的运行时间对应于操作的次数 sum ++被执行。

当唯一的区别是n循环测试等于if时,上述两种算法的时间复杂度如何相差1?我如何计算这样一个问题的O(n)复杂度?

1 个答案:

答案 0 :(得分:1)

算法A

让我们调用f(n)在外循环级别聚合的操作数,g(n)为第一个内循环,h(n)为最内循环。

我们可以看到

  • f(n) = sum(i=1; i < 2n; g(i))
  • g(i) = sum(j=1, j < i*i; h(j))
  • h(j) = sum(k=1; k < j; 1 if j%i = 1, else 0)

j%i = 1 j从1到i*i的变化次数是多少? i的以下值恰好j次:

j = 0.i + 1
j = 1.i + 1
j = 2.i + 1
...
j = (i-1)*i + 1

所以:

h(j) = sum(k=1; k < j; 1 if `j%i = 1`, else 0)
     = i

=> g(i) = sum(j=1, j < i*i; h(j))
        = sum(j=1, j < i*i; i)
        = i*i * i = i^3

=> f(n) = sum(i=1; i < 2n; g(i))
        = sum(i=1; i < 2n; i^3)
        <= sum(i=1; i < 2n; 16.n^3)   // Here just cap every i^3 with (2n)^3
        <= 32.n^4

=> f(n) = O(n^4)

算法B
(使用与算法A相同的命名约定)

我们将j%i投射到true的次数是多少?每次j%i与0不同。这次发生了多少次?我们需要删除ji的倍数的事件,i2.i,... (i-1).i。整数1到i*i,其中包含i*i个数字。此数量为i*i - (i-1) = i^2 - i + 1

结果,

h(j) = sum(k=1; k < j; 1 if j%i = 1, else 0)
     = i^2 - i + 1
     = i^2 // dropping the terms i and 1 which are dominated by i^2 as i -> +Inf. 

=> g(i) = sum(j=1, j < i*i; h(j))
        = sum(j=1, j < i*i; i^2)
        = i*i * i^2
        = i^4

=> f(n) = sum(i=1; i < 2n; g(i))
        = sum(i=1; i < 2n; i^4)
        <= sum(i=1; i < 2n; 32.n^4)   // Here just cap every i^4 with (2n)^4
        <= 64.n^5

=> f(n) = O(n^5)

底线

算法A和B之间复杂性的差异来自以下事实:

  • i
  • j值为i%j = 1
  • i^2 - i + 1
  • j值为i%j <> 0