Big O:如何根据外部for循环确定for循环增量的运行时间?

时间:2016-12-31 11:01:44

标签: algorithm runtime time-complexity big-o

我有以下算法,运行时复杂度为O(N ^ 2),但我希望对它有更深入的了解,而不仅仅是记住常见的运行时。

在内部for循环考虑中使用i+1分解并分析它的正确方法是什么?

void printunorderedPairs(int[] array) {
    for(int i=0; i<array.length; i++) {
        for(int j=i+1; j<array.length; j++) {
            System.out.println(array[i] + "," + array[j]);
        }
    }
}

修改

询问如何分析特定问题

2 个答案:

答案 0 :(得分:1)

  

分解并分析它的正确方法

拿铅笔和纸,放下一些未打开的环:

     i        inner loops per i
-------------------------------
     1               length - 1  
     2               length - 2
    ..                       ..  
     k               length - k 
    ..                       ..
length - 1                    1
length                        0

现在,为了获得所需的总时间,让我们总结内部循环:

 (length - 1) + (length - 2) + ... + (length - k) ... + 1 + 0

这是一个算术级数,其总和是

 ((length - 1) + 0) / 2 * length == length**2 / 2 - length / 2 = O(length**2)

答案 1 :(得分:0)

T =内循环运行的次数。

大约一半时间,i<array.length/2时,它至少运行array.length/2次。因此,对于大约array.length / 2外部迭代,内部循环至少运行array.length / 2次,因此:

T >= (N/2)*(N/2)
i.e.,
T >= N²/4

这是O(N²)。但是,对于所有 array.length外部迭代,内部循环最多运行 array.length次,所以:

T <= N*N, i.e.,
T <= N²

这也是O(N²)。由于我们的时间上限和下限均为O(N²),因此我们知道T在O(N²)中。

注意:从技术上讲,我们只需要上限来表明T在O(N²)中,但我们通常会寻找尽可能紧的边界。 T实际上是Ө(N²)。

另请注意:上面使用 half 并没有什么特别之处 - 任何常数比例都可以。这些是一般规则:

  1. 下限:如果至少Ω(N)工作至少Ω(N)次,则表明您正在进行Ω(N²)工作。 Ω(N)*Ω(N)=Ω(N²)

  2. 上限:如果你最多O(N)工作最多O(N)次,你正在进行O(N²)工作。 O(N)* O(N)= O(N²)

  3. 由于我们都有,我们可以使用:Ω(N²)∩O(N²)=Ө(N²)