嵌套回路的时间复杂性 - 始终只是它们每个分开的乘法吗?

发布于 2025-02-05 04:14:22 字数 206 浏览 3 评论 0原文

例如,在查看此代码时:

for (int i = 1; i < n; i*=2)
  for (int j = 0; j < i; j +=2)
  {
    // some contstant time operations
  }

这么简单说,因为外循环是日志,并且内部循环是n,因此结果结合了NLOGN的大(O)?

When looking at this code for example :

for (int i = 1; i < n; i*=2)
  for (int j = 0; j < i; j +=2)
  {
    // some contstant time operations
  }

Is it as simple as saying that because the outer loop is log and and inner loop is n , that combined the result is big(O) of nlogn ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界如花海般美丽 2025-02-12 04:14:22

这是问题中对示例的分析。为简单起见,我将忽略内部循环中2的增量,并将其视为1,因为就复杂性而言,它无关紧要 - 内部循环在i2的常数因子无关紧要。
因此,我们可以注意到,外循环正在产生i值,这是2n封顶的功能,也就是说:

1, 2, 4, 8, ... , 2^(log2 n)

这些数字这也是内部循环中每个i的“恒定时间操作” “恒定时间操作”的数字。
因此,我们要做的就是总结上述系列。很容易看出这些是几何系列:

2^0 + 2^1 + 2^2 + ... + 2^(log2 n)

它具有众所周知的解决方案:

(来自 wiki

我们有a = 1 a = 1r = 2和...良好n_from_the_image = log n。在这里,我们对不同变量有相同的名称,因此这是一个问题。

现在,让我们替换并获得该总和

(1-2^((log2 n) + 1) / (1 - 2) = (1 - 2*n) / (1-2) = 2n-1

是线性o(n)复杂性。

Here is the analysis of the example in the question. For simplicity I will neglect the increment of 2 in the inner loop and will consider it as 1, because in terms of complexity it does not matter - the inner loop is linear in i and the constant factor of 2 does not matter.
So we can notice, that the outer loop is producing is of values which are powers of 2 capped by n, that is:

1, 2, 4, 8, ... , 2^(log2 n)

these numbers are also the numbers that the "constant time operation" in the inner loop is running for each i.
So all we have to do is to sum up the above series. It is easy to see that these are geometric series:

2^0 + 2^1 + 2^2 + ... + 2^(log2 n)

and it has a well known solution:
enter image description here

(from Wiki )

We have a=1, r=2, and... well n_from_the_image =log n. We have a same name for different variables here, so it is a bit of a problem.

Now let's substitute and get that the sum equals

(1-2^((log2 n) + 1) / (1 - 2) = (1 - 2*n) / (1-2) = 2n-1

Which is a linear O(n) complexity.

咽泪装欢 2025-02-12 04:14:22

通常,我们将o时间复杂性作为执行最终循环的次数(在这里我们假设最内在的循环由o的语句组成(( 1)时间复杂性)。


考虑您的榜样。第一个循环执行o(log n)次,第二个最内向的循环执行o(n)次。如果某物o(n)正在执行o(log n)次,那么是的,最终的时间复杂性只是它们乘以:o(n log n og n log n )

通常,这与大多数嵌套的循环有关:您可以假设它们的大时段复杂性是每个循环的时间复杂性,乘以乘。


但是,当您可以考虑Break语句时,此规则有例外。如果循环有可能提早爆发,那么时间的复杂性将有所不同。

看看这个示例我刚刚想到:

for(int i = 1; i <= n; ++i) {
    int x = i;
    while(true) {
        x = x/2;
        if(x == 0) break;
    }
}

嗯,最内向的循环是o(infinity),所以我们可以说总的时间复杂性是o(n) * o( Infinity)= O(Infinity)?否。在这种情况下,我们知道最内向的循环将始终突破o(log n),给出了总o(n log n)时间复杂性。

Generally, we take the O time complexity to be the number of times the innermost loop is executed (and here we assume the innermost loop consists of statements of O(1) time complexity).


Consider your example. The first loop executes O(log N) times, and the second innermost loop executes O(N) times. If something O(N) is being executed O(log N) times, then yes, the final time complexity is just them multiplied: O(N log N).

Generally, this holds true with most nested loops: you can assume their big-O time complexity to be the time complexity of each loop, multiplied.


However, there are exceptions to this rule when you can consider the break statement. If the loop has the possibility of breaking out early, the time complexity will be different.

Take a look at this example I just came up with:

for(int i = 1; i <= n; ++i) {
    int x = i;
    while(true) {
        x = x/2;
        if(x == 0) break;
    }
}

Well, the innermost loop is O(infinity), so can we say that the total time complexity is O(N) * O(infinity) = O(infinity)? No. In this case we know the innermost loop will always break in O(log N), giving a total O(N log N) time complexity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文