【问题标题】:Having trouble finding time-complexity of nested for loop难以找到嵌套 for 循环的时间复杂度
【发布时间】:2014-09-21 23:12:17
【问题描述】:

所以我一直在尝试使用以下算法找到大复杂度:

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

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

【问题讨论】:

  • 内循环可以重写。看我的回答。

标签: loops nested big-o complexity-theory


【解决方案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强>.
所以求和的总数可以写成

求和 = 总和(从 i = 1 到 n)[n/i]

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

【讨论】:

  • 您可能希望仔细检查。 j 的循环边界似乎不依赖于 i 的循环边界。所以,这应该看起来像: (0,1, 2, ...n-1),(0,1,2, ... n-1) ... (0,1,2, ... n-1) 重复 n 次。
  • 我认为我的总结是正确的,因为内循环递增为 j = j+i。如果它是 j = j+1,就会是你提到的情况
  • 我的立场是正确的。我将 i 误读为内部循环中的 1。
【解决方案2】:

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

首先,只考虑:

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

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

现在,只考虑:

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

其中 k 是一个常数正整数项(如 1、2、3、... 等),k &lt;= n

在这种情况下 var i 采用从 0 到 n-1 的所有整数值范围。比如让k=2,那么我们可以用下图来表示正在发生的事情:

您看到的黑色是可能整数的区间,红色表示 var i 所采用的实际整数值。如您所见,var i 正在“跳过”奇数以达到 n-1,因此在这种情况下(当 k=2 时)只取偶数。

结果,当k=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

因此,复杂度由以下两个嵌套求和给出:

首先,从内部求和(右侧)开始评估:

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

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

现在,如果你只是扩展最后一个总和,结果是:

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

这可以表示为:

请注意,从该分析中,您可以获得渐近紧界。

顺便说一句:您可以检查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]

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2021-02-15
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多