大O表示法- 寻找复杂性

huangapple go评论64阅读模式
英文:

Big O Notation- Finding the Complexity

问题

以下是翻译好的内容:

我正在处理一个测验 - 我对所有的问题都回答正确,但以下代码片段有困惑。帮我理解一下这将是哪种符号表示法?

我的选择是:O(n^2),O(n^3),O(nlogn),以及O(n+n^2)

代码片段如下:

for (int i = 0; i < n; i++) { 
  System.out.println("hello");
} 
for (int i = 0; i < n; i++) { 
  for (int j = 0; j < i; j++) { // 注意这里的 j < i。
    System.out.println("hello");
  }
}
英文:

I'm working on a quiz- I got all right but the following snippet. Help me understand which notation this would be?

My selections are: O(n^2), O(n^3), O(nlogn), and O(n+n^2)

Snippet is:

   for (int i = 0; i &lt; n; i++) { 
     System.out.println(&quot;hello&quot;);
   } 
   for (int i = 0; i &lt; n; i++) { 
     for (int j = 0; j &lt; i; j++) { // NOTE j &lt; i here. 
       System.out.println(&quot;hello&quot;);
     }
  } 

答案1

得分: 2

第一个循环很简单:循环体恰好运行了 n 次,因此是 O(n)

第二个循环需要更多思考。外部循环明显运行了 n 次,但内部循环体被执行的次数是多少呢?第一次通过外部循环时,我们有 i == 0,因此内部循环体不会执行任何次数(即使对于 j == 0j < i 也为假)。第二次时,i == 1,因此内部循环体执行了 1 次。一般情况下,它执行了 i 次,其中 i = 0, ..., n-1

因此,内部循环体的总执行次数,我们称之为 S,是 S = 0 + 1 + ... + n-1。现在有一个很好的技巧可以将其转化为一个闭合形式的方程。将其写下一次,然后再反向写一次:

 S =  0  +  1  + ... + n-2 + n-1
 S = n-1 + n-2 + ... +  1  +  0

然后将这两个方程相加:

 S  =  0  +  1  + ... + n-2 + n-1
 S  = n-1 + n-2 + ... +  1  +  0
------------------------------- +
2*S = n-1 + n-1 + ... + n-1 + n-1

因此 2*S 等于 n 乘以 n-1。从此,我们很容易得出 S = n * (n-1) / 2。这可以重写为 S = &#189;*n^2 - &#189;*n。在大 O 表示中,只有最高阶的项保留下来,常数 &#189; 并不重要,因此是 O(n^2)

另一种更为简化的方式是:内部循环平均运行了 n/2 次(加减一个),外部循环再次运行了 n 次,这同样得到了 O(&#189;*n*n) = O(n^2)

与第一个循环的 O(n) 结合起来,相对于 O(n^2),它变得渐近上不重要,因此预期的答案可能是 O(n^2)

但需要注意的是,从技术上讲,O(n+n^2) 也是正确的,因为 O(n + n^2) = O(n^2)。同样,较低阶的项 n 在渐近意义下不重要。甚至 O(n^3) 从技术上讲也是正确的,因为 n^3 会主导 n^2;然而,复杂度既不是 Ω(n^3),也不是 θ(n^3)

英文:

The first loop is easy: the body runs exactly n times, so it's O(n).

The second one requires a bit more thinking. It's clear that the outer loop runs n times, but how often is the inner loop body executed? The first time through the outer loop, we have i == 0, so the inner loop body is executed 0 times (j &lt; i is false even for j == 0). The second time, i == 1 so the inner loop body is executed 1 times. In general, it's executed i times, for i = 0, ..., n-1.

So the total number of executions of the inner loop body is, let's call it S, is S = 0 + 1 + ... + n-1. Now there's a nice trick to make that into a closed form equation. Write it down once, and then once more in reverse:

 S =  0  +  1  + ... + n-2 + n-1
 S = n-1 + n-2 + ... +  1  +  0

Then add the two equations together:

 S  =  0  +  1  + ... + n-2 + n-1
 S  = n-1 + n-2 + ... +  1  +  0
------------------------------- +
2*S = n-1 + n-1 + ... + n-1 + n-1

So 2*S is equal to n times n-1. From this, we easily find S = n * (n-1) / 2. This can be rewritten as S = &#189;*n^2 - &#189;*n. In the big-O form, only the highest order term survives, and the constant &#189; does not matter, so this is O(n^2).

A more "handwavy" way to get the same result is: the inner loop runs, on average, n/2 times (give or take one), and the outer loop runs n times, again giving O(&#189;*n*n) = O(n^2).

Combined with the O(n) of the first loop, which becomes asymptotically irrelevant compared to the O(n^2), the expected answer is probably O(n^2).

But note that technically O(n+n^2) is also correct because O(n + n^2) = O(n^2). Again, the lower order term n does not matter asymptotically. Even O(n^3) is technically correct because n^3 dominates n^2; however, the complexity is neither Ω(n^3) nor θ(n^3).

答案2

得分: 1

第一个循环是线性的,因此复杂度只有 O(N)

然而,对于第二/第三个循环,第二个循环是一个循环,循环了 N 次。内部循环会运行 N/2 次,因为 j 始终小于 i(而且永远不相等)。因此,这些循环的复杂度是 N(N/2),或者 N^2/2。因为大O表示法中的常数不重要,N/2N - 1 所花费的时间是相同的,所以我们也可以说它是 N(N-1),或者 N^2 - N

如果将两个复杂度相加,我们得到 (N) + (N^2 - N),得到 N^2。因此最终的结果是 O(N^2)

英文:

(This is what I think, I can't comment because I don't have enough reputation but I wanted to throw this out)

The first loop is linear and thus has the complexity of just O(N).

However, for the second/third loop, the second loop is a loop that loops N times. The inner loop will run N/2 time because j is always going to be less than i, (and never equal). Thus, the complexity for these loops is N(N/2), or N^2/2. Because Big O is a constant, N/2 and N - 1 are the same time, so we can also say that it is N(N-1), or N^2 - N.

If we add both complexities together, we have (N) + (N^2 - N), we get N^2. Thus the final result is O(N^2).

huangapple
  • 本文由 发表于 2020年9月7日 02:06:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63767365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定