这个嵌套三重循环的复杂性是多少?

时间:2013-08-28 11:25:18

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

我在StackOverflow上搜索了一下,并且已经理解了j循环的复杂性,即O(n2)。然而,随着嵌套添加k循环,我很困惑为什么复杂性变为O(n3)。有人能帮助我理解这个吗?

根据我的理解,i-loop有n次迭代,j-loop有1 + 2 + 3 + ... + n次迭代n*(n+1)/2,即O(n2)

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(n2)。 K的模式难以发现,但众所周知K取决于J,因此:

k = ((n+4)/3)*j = (n*(n-1)*(n+4))/6复杂度为O(n3)

我希望这将有助于将来的人们。

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

5 个答案:

答案 0 :(得分:12)

如果你已经习惯了Sigma Notation,这是一种推断算法时间复杂度的正式方法(精确的嵌套循环):

enter image description here

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

答案 1 :(得分:5)

k循环具有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个循环

答案 2 :(得分:1)

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

本质上,如果你逐行评估它,你会得到类似O(n ^ 3 / C)的东西,其中C是一些常数,通常在这样的评估中被跳过,导致O(n ^ 3)。

答案 3 :(得分:1)

在没有图表的情况下解释这是非常棘手的,但每个嵌套循环将在将迭代返回到父级之前迭代“n”次。

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

将代码放入调试器中,以便直观地指示机器如何处理这种复杂性。

答案 4 :(得分:1)

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

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

外循环执行N次。每次外循环执行时,内循环执行M次。因此,内循环中的语句总共执行N * M次。
因此,两个循环的总复杂度为O(N2)。
类似地,三个循环的复杂性是O(N3)