无法找到嵌套for循环的时间复杂度

时间:2014-09-21 23:12:18

标签: loops nested big-o complexity-theory

所以我一直试图使用以下算法找到大哦复杂性:

for (i = 1; i ≤ n;i + +)
     for (j = 0; j < n; j = j + i)
          print(Array[j]);

我被告知最佳方式是使用求和表示,我知道它可以用某种形式的系列表示,我真的不知道从哪里开始。我可以看到外部循环迭代n次,但内部循环是我得到的东西。我希望我能在这里推动正确的方向而不是答案。

2 个答案:

答案 0 :(得分:1)

如果扩展两个for循环中的汇总数。数组索引应如下所示

  
    

(0,1,2,...... n-1),(0,2,4,... n-1),(0,3,6,9 ...... n-1) .....(0,N / 2),(0)

  

如果我们观察到第一个括号 n ,则第二个括号 n / 2 ,依此类推,直到最后一个括号 1
所以总和的总数可以写成

  
    

Summations = Sum(从i = 1到n)[n / i]

  

尝试求解求和,您将得到求和总数

答案 1 :(得分:0)

让我们按照你的建议使用求和,以获得更加分析/代数的方法。

首先,只考虑:

for (i = 1; i <= n; i++)
    //some O(1) operation

这很简单,因为var i获取从1到n的所有整数值范围。 我们可以用以下求和来表达这个循环:

sum 1

现在,仅考虑:

for (j = 0; j < n; j = j + k)
    //some O(1) operation

其中k是常数正整数项(如1,2,3,......等),k <= n

在这种情况下,var i 获取从0到n-1的所有整数值范围。例如,让k=2,然后我们可以在下图中表示正在发生的事情:

range k2

您在黑色中看到的是可能整数的间隔,红色代表var i所需的实际整数值。如你所见,var i在奇数上“跳”到n-1,所以在这种情况下(当k=2时)只取偶数。

结果,当k=2时,复杂性由求和给出:

sum 2

通常,可以对任何k进行类似的方法。特别要注意的是,当k倾向于n时,复杂性往往会降低。

出于我们的目的,我们可以重写循环:

for (j = 0; j < n; j = j + k)

如:

for (j = 0; j < n/k-1; j++) 

两者都具有相同的复杂性。

最后,请考虑:

for (i = 1; i <= n; i++)
     for (j = 0; j < n; j = j + i)
          //some O(1) operation

在内圈中,我们i扮演的角色与k之前相同。这意味着内部循环将以1到n范围内的i的每个可能值执行。

重写为:

for (i = 1; i <= n; i++)
     for (j = 0; j < n/k-1; j++)
          //some O(1) operation

因此,复杂性由以下两个嵌套的总结给出:

enter image description here

首先,开始使用内部求和(右边的)进行评估:

enter image description here

注意我意外地将var名称从i更改为x,但这并不重要。

我们在这里得到了另一张海报给出的完全相同的结果。

现在,如果您只是展开最后一次求和,结果为:

enter image description here

现在括号中的是 n次谐波数,不要与谐波系列混淆。这是离散数学(和其他领域)中有趣的数字。

这可以表示为:

enter image description here

请注意,通过此分析,您可以获得渐近紧束缚。

BTW:您可以查看此link

中的最后一个等式

语法为:

Sum[Sum[1, {j, 0, (n/i)-1}], {i, 1, n}]=Sum[n/x, {x, 1, n}]=n*Sum[1/x, {x, 1, n}]=n*(1+1/2+1/3+...+1/n)=n*HarmonicNumber[n]

我希望这会有所帮助。