【问题标题】:3 Nested for loops where third loop is dependent on first time complexity3 嵌套 for 循环,其中第三个循环取决于第一次时间复杂度
【发布时间】:2022-09-18 22:37:41
【问题描述】:

我试图找到 3 个嵌套 for 循环的时间复杂度。我对如何做到这一点有点迷茫,因为第一个和第三个是依赖的。根据我所做的,我发现模式是 n(1 + 2 + 3) 所以 O(n^2) 但我不确定这是否正确。我也不确定这是否包括 j 循环,或者我是否必须将 n 乘以我当前的答案。任何帮助深表感谢。

for (int i = 0; i < n*n; i++) {
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < i; k++) {
            // print some statement here
        }
    }
}

标签: time-complexity big-o


【解决方案1】:

简短的回答:

假设最里面的循环操作是O(1),你的代码的时间复杂度是O(n^5).

更长的答案:

让我们从一个更简单的例子2个依赖循环:

for (int i=0; i<n; ++i) {
    for (int j=0; j<i; ++j) {
        // Some O(1) operation
    }
}

外循环将运行 n 次,内循环将运行 1...n 次,平均而言:

(1 + 2 + ... + n)/n = n(n+1)/2/n =上)

所以这个更简单的例子的整体复杂性是O(n^2).

现在到你的情况:
请注意,我假设最内层循环中的操作是在O(1).

for (int i=0; i< n*n; i++){
   for (int j=0; j<n; j++){
       for (int k=0; k<i; k++){
          // Some O(1) operation
       }
   }
}

第一个外循环将运行 n^2 次。
第二个外循环(即中间循环)将运行 n 次。
所以2个外循环将一起运行O(n^3).
现在内部循环平均运行的次数是O(n^2)因为迭代次数现在将是 1..n^2(而不是 1..n):

(1 + 2 + ... n^2)/n^2 = (n^2)(n^2+1)/2/(n^2) = O(n^2)。

因此总时间复杂度为O(n^5).


附录:
下面的代码是不是在任何情况下都是关于复杂性的证明,因为测量 n 的特定值不证明关于时间函数的渐近行为的任何信息,但它可以让您对已完成的操作数量有“感觉”。

#include <iostream>
#include <ctype.h>

void test(int n)
{
    int64_t counter = 0;
    for (int i = 0; i < n * n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < i; k++) {
                counter++;
            }
        }
    }
    std::cout << "n:" << n << ",  counter:" << counter << std::endl;
}

int main()
{
    test(10);
    test(100);
    test(1000);
}

输出:

n:10,  counter:49500
n:100,  counter:4999500000
n:1000,  counter:499999500000000

我相信很明显,操作的数量接近 n^5/2,因为像 1/2 这样的常数不适用:O(n^5).

【讨论】:

  • 在您的最终观察中,可能值得澄清的是,常数(在本例中为 1/2)不适用于复杂性估计。
  • @Chris我认为这很明显,因此没有提及(问题的级别不是那么基本)。但请随时编辑我的答案,并在您认为最合适的地方添加说明。
  • 抱歉,没有办法获得 O(n^5) 的时间复杂度,关于第一个循环,你想用 n^2 解释什么?我不同意你的说法“因为迭代次数现在将是 1..n^2(而不是 1..n)”我保持它非常简单,忽略每个循环为每个项目迭代运行 O(1) 的依赖关系。我没有看到比 O(n^3) 更进一步的方法,根本没有反对意见,因为在某些情况下,时间复杂度可能小于 n^3
  • @jmvcollaborator 正如您在我发布的测试结果中看到的那样,复杂性很明显不是O(n^3)。当然,我的测试不是数学证明(正如我自己指出的那样),但在这种情况下,很明显 O(n^3) 不能成为给定 n 所需操作数的上限。您可以自己运行我的代码并看到相同的结果。
  • 我会保持这个非常简单......只要在两者之间有一些奇怪的东西而不是增加每个循环上处理项目的数量,复杂性就不能大于 n^3。但无论每个循环如何或如何每个项目执行 O(1)。无意打扰您,但我希望有一个工作示例或具体解释,其中复杂性超出 N^3 我们都在这里学习,谢谢好友并接受我的评论投票。
猜你喜欢
  • 2021-02-15
  • 2018-04-07
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
相关资源
最近更新 更多