【问题标题】:What is the complexity of this nested triple for loop?这个嵌套三重 for 循环的复杂性是多少?
【发布时间】:2013-08-28 11:25:17
【问题描述】:

我在 StackOverflow 上进行了一些搜索,并了解了 j-loop 的复杂性,即O(n<sup>2</sup>)。然而,随着 k-loop 的嵌套添加,我很困惑为什么复杂性变成O(n<sup>3</sup>)。有人可以帮我理解这一点吗?

据我了解,i-loop 有 n 次迭代,j-loop 有 1+2+3+...+n 次迭代 n*(n+1)/2O(n<sup>2</sup>)

for(i = 1; i < n; i++) {   
    for(j = i+1; j <= n; j++) {
        for(k = i; k <= j; k++) {
           // Do something here...
        }
    }
}

编辑:感谢您的所有帮助 :) Balthazar,我已经编写了一段代码,它将根据计数器所在的循环递增计数器,这是一种粗略的分步方式-步骤:

#include <iostream>

int main(int argc, const char * argv[])
{
    int n = 9;
    int index_I = 0;
    int index_J = 0;
    int index_K = 0;
    for (int i = 1; i < n; i++) {
        for (int j = i+1; j <= n; j++) {
            for (int k = i; k <= j; k++) {
                index_K++;
            }
            index_J++;
        }
        index_I++;
    }
    std::cout << index_I << std::endl;
    std::cout << index_J << std::endl;
    std::cout << index_K << std::endl;
    return 0;
}

我将这段代码从 n=2 运行到 n=9,增量为 1,得到以下序列:

因此,从计数器可以看出: i = n-1 给出了 O(n) 的复杂度,而 j = ((n-1)*n)/2 给出了复杂度 O(n<sup>2</sup>)。 K 的模式很难发现,但已知 K 取决于 J,因此:

k = ((n+4)/3)*j = (n*(n-1)*(n+4))/6 的复杂度为O(n<sup>3</sup>)

我希望这对未来的人们有所帮助。

EDIT2:感谢Dukeling 的格式化 :) 在最后一行也发现了一个错误,现在更正

【问题讨论】:

    标签: algorithm complexity-theory big-o time-complexity


    【解决方案1】:

    如果您习惯使用 Sigma 表示法,这里有一个正式的方法来推断您的算法的时间复杂度(精确的普通嵌套循环):

    注意:公式简化可能包含错误。如果您发现任何东西,请告诉我。

    【讨论】:

    • 请您解释一下您是如何进入第三步的,好吗? – j 从到 i+1 到 n 的总和
    • 你熟悉link中的求和吗?如果是这样,将 j = 1 中的 1 交换为 j = i + 1 将得到上述总和。见link
    • 感谢您的回复。谢谢。
    【解决方案2】:

    k-loop 的复杂度为 O(j-i)

    j 循环的复杂度为 O((n-i)*(n-i))

    i-loop 的复杂度为 O(n*n*n)=O(n^3)

    不管怎样,你知道它不是 O(n^2),因为前两个循环是 O(n^2),它不会超过 O(n^3),因为只有 3 个循环

    【讨论】:

    • 三个循环的复杂度可能大于 O(n^3)。
    【解决方案3】:

    查看this 示例以评估最坏情况的复杂性。

    本质上,如果您逐行评估它,您将得到类似 O(n^3 / C) 的结果,其中 C 是某个常数,通常在此类评估中被跳过,导致 O(n^3)。

    【讨论】:

      【解决方案4】:

      这在没有图表的情况下很难解释,但每个嵌套循环都会在将迭代返回给父级之前迭代“n”次。

      正如 jambono 指出的那样,每个嵌套循环都需要对“n”的每次迭代进行比较/评估。因此,“n”与每个循环中的局部变量 (n*n*n) 进行比较,使得 O(n^3)。

      在调试器中单步执行代码,以直观地指示机器如何处理这种复杂性。

      【讨论】:

        【解决方案5】:

        首先,我们将考虑内部循环的迭代次数与外部循环的索引值无关的循环。例如:

        for (i = 0; i < N; i++) {
              for (j = 0; j < M; j++) {
                     sequence of statements
              }
          }
        

        外循环执行N次。每次外循环执行,内循环执行M次。结果,内部循环中的语句总共执行了 N * M 次。
        因此,两个循环的总复杂度为 O(N2)。
        同样,三个循环的复杂度是 O(N3)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-02
          • 1970-01-01
          • 1970-01-01
          • 2022-08-12
          • 2021-02-15
          相关资源
          最近更新 更多