我是否过度简化了计算复杂度

时间:2018-09-14 02:26:56

标签: time-complexity big-o

我只是想计算某些程序片段的复杂度,但是我担心自己做的太简单了。如果我放下片段和答案,您能告诉我我做错了什么吗?

(a)

sum = 0;
for (i = 0;i < n;i++)
    sum++;

答案:n,只有一个for循环

(b)

sum = 0;
for (i = 0;i < n;i++)
    for (k = 0;k < n*n;k++)
        sum++;

答案:因为嵌套循环,所以n ^ 2,尽管我想知道嵌套循环中的n * n是否使它成为n ^ 3

(c)

sum = 0;
for (i = 0;i < n;i++)
    for (k = 0;k < i;k++)
        sum++;

答案:n ^ 2

(d)

sum = 0;
for (i = 0;i < n;i++)
    for (k = 0;k < i*i;k++)
        sum++;

答案:n ^ 2,但我和b有同样的担忧

(e)

sum= 0;
for (i = 0;i < n;i++)
    for (k = i;k < n;k++)
        sum++;

答案:n ^ 2

1 个答案:

答案 0 :(得分:0)

由于在您的所有示例中,主要操作都是sum++,所以我们必须计算该基本操作的执行次数。

此外,在所有情况下,还有i++k++也很重要。最后,必须在每个步骤将这些计数器与它们的限制进行比较,并且我们还应该考虑这些比较。现在,这些额外的操作不会更改迭代次数。它们只是使每次迭代变得更加昂贵。例如,

(a)

sum = 0;
for (i = 0;i < n;i++)
  sum++;

重复n次:i++sum++i<n,所有这些都使3n操作具有相似的复杂性。这就是总复杂度为O(n)的原因。

一旦了解了这一点,就不再需要对复杂性进行详细分析,因为big-O表示法将处理这些额外的计算。

第二个例子

sum = 0;
for (i = 0;i < n;i++)
  for (k = 0;k < n*n;k++)
    sum++;

重复n次操作

  for (k = 0;k < n*n;k++)
    sum++;

由于前一种情况,此操作的复杂度为O(n*n),因为这里的限制是n*n而不是n。因此,总复杂度为O(n*n*n)

第三个示例是相似的,只是这次执行的操作n次是

for (k = 0;k < i;k++)
    sum++;

,其复杂度随i而变化。因此,我们不必将n乘以n,而是将不同的东西相加:

O(1) + O(2) + ... + O(n)

,由于O中隐含的常数因子始终是相同的(=每个基本步骤要增加或比较的变量数),我们可以将其重写为

O(1 + 2 + ... + n) = O(n(n+1)/2) = O(n*n)

其他示例很相似,可以按照这些相同的想法进行分析。