(n ^ 2)的大O表示法

时间:2013-06-17 06:54:12

标签: java big-o time-complexity

示例1

for (int i = 0; i < n; i++) {
  for (int j = 0; j < n; j++) {
        System.out.println(count++);
   }
}

示例2

for (int i = 0; i < n * n; i++) {            
     System.out.println(count++);
} 

两个例子都给了我一个大O(n ^ 2)。但哪个是最好的?

3 个答案:

答案 0 :(得分:2)

要查找最佳代码,最好编译它并使用javap -c ClassName.class查看两种方法生成的字节码。我对前者使用foo方法,后者使用bar方法。

public static void foo(int n) {
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            System.out.println(count++);
        }
    }
}

public static void bar(int n) {
    int count = 0;
    for (int i = 0; i < n * n; i++) {
        System.out.println(count++);
    }
}

结果如下:

public static void foo(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iconst_0      
       3: istore_2      
       4: iload_2       
       5: iload_0       
       6: if_icmpge     38
       9: iconst_0      
      10: istore_3      
      11: iload_3       
      12: iload_0       
      13: if_icmpge     32
      16: getstatic     #2       // Field java/lang/System.out:Ljava/io/PrintStream;
      19: iload_1       
      20: iinc          1, 1
      23: invokevirtual #3       // Method java/io/PrintStream.println:(I)V
      26: iinc          3, 1
      29: goto          11
      32: iinc          2, 1
      35: goto          4
      38: return        

public static void bar(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iconst_0      
       3: istore_2      
       4: iload_2       
       5: iload_0       
       6: iload_0       
       7: imul          
       8: if_icmpge     27
      11: getstatic     #2       // Field java/lang/System.out:Ljava/io/PrintStream;
      14: iload_1       
      15: iinc          1, 1
      18: invokevirtual #3       // Method java/io/PrintStream.println:(I)V
      21: iinc          2, 1
      24: goto          4
      27: return        

最后,由于操作较少,后一种实现似乎比前者更好。

我不是这方面的专家,所以如果有人可以编辑/执行更好的分析,请随意这样做。我写了这个答案,因为它不符合一条评论。

答案 1 :(得分:0)

两个循环都是相同的。没有最好的。但是如果N值很大,则N*N值将溢出,您需要返回两个for循环。因此,您可以根据N值使用此功能。

答案 2 :(得分:0)

当你说最好的时候,在程序意义上,有两种方法可以定义,在内存和性能方面(通常是迭代)。

就内存而言,第二个是最好的,因为只使用了2个变量(i和n)。 与此同时,每次迭代仅发生一次变量赋值(i ++ =&gt; i = i + 1)。 而在第一个,i ++和j ++中,每次迭代都会发生两次分配操作。 由于重新分配变量在高处理操作中也需要相当长的时间,因此第二个是最好的。

就迭代而言,两者都是相同的。