大O符号-寻找复杂性

时间:2020-09-06 18:06:07

标签: java data-structures big-o

我正在做一个测验-除以下片段外,我一切都很好。帮助我了解这是哪种表示法?

我的选择是: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++) { // NOTE j < i here. 
       System.out.println("hello");
     }
  } 

2 个答案:

答案 0 :(得分:2)

第一个循环很简单:主体精确运行n次,所以运行O(n)

第二个需要更多的思考。显然,外循环运行了n次,但是内循环主体多久执行一次?第一次通过外循环,我们有i == 0,所以内循环主体被执行0次(j < i也为j == 0是错误的)。第二次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 = ½*n^2 - ½*n。在big-O形式中,只有最高阶的项保留下来,常数½无关紧要,因此O(n^2)就是这样。

获得相同结果的另一种“手摇式”方法是:内部循环平均运行n/2次(给定或取一个),而外部循环再次运行n次给O(½*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)

答案 1 :(得分:1)

(这就是我的想法,我没有评论,因为我没有足够的声誉,但是我想把它排除在外)

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

但是,对于第二个/第三个循环,第二个循环是循环N次的循环。内部循环将运行N/2时间,因为j总是小于i(并且永远不等于)。因此,这些循环的复杂度为N(N/2)N^2/2。由于Big O是一个常数,N/2N - 1是同一时间,所以我们也可以说它是N(N-1)N^2 - N

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