为什么这个O(N ^ 3)而不是O(N ^ 4)?

时间:2018-11-07 23:20:57

标签: java big-o

public static int g(LinkedList<Integer> list) {
    int t = 0;

    for (int i = 0; i < list.size(); i++) {
        int tgt = list.get(i);

        for (int j = i + 1; j < list.size(); j++) {
            if (list.get(j) == tgt) 
                t += list.get(j);
        }
    }

    return t;
}

if语句是否会使复杂度为O(N ^ 4)?

2 个答案:

答案 0 :(得分:3)

if语句与时间复杂度无关-if语句的操作具有时间复杂度O(1),但是if语句中的工作可能具有更大的时间复杂度。

这是因为list.get(i)属于O(n)。要获取LinkedList的第n:th个元素,您需要在列表中移动n次才能找到它。这是因为LinkedList不会保存其索引,只会保存列表中的第一个和最后一个元素,然后再保存其直接邻居。

这是每个功能的时间复杂度:

public static int g(LinkedList<Integer> list) {
    int t = 0;

    for (int i = 0; i < list.size(); i++) {           // O(n) - loop
        int tgt = list.get(i);                        // O(n)

        for (int j = i + 1; j < list.size(); j++) {   // O(n) - loop
            if (list.get(j) == tgt)                   // O(n)
                t += list.get(j);                     // O(n)
        }
    }

    return t;
}

由于仅迭代2个循环,因此最初将使时间复杂度O(n^2)list.get(i)的3个调用将使每个调用的时间复杂度为O(n),从而导致3*O(n)。但是,默认将其设置为O(n),并将最终时间复杂度设置为O(n) * O(n) * 3*O(n) => O(n^3)

额外

不相关的笔记:您看到,当两次调用list.get(j)时,在最内层的循环中,即使您刚刚得到该程序,也会使程序在列表上进行两次迭代。值。

if (list.get(j) == tgt)
    t += list.get(j);

可能是处理器或编译器会对此进行优化,并将值保存在缓存中,但是最好一次调用list.get(j)并存储其值。

答案 1 :(得分:2)

如果语句不是循环。

每个get可以取O(n),但其主体中的语句在条件之后执行。因此if语句的取值是O(n)+ O(n)(对于两次获取),即O(n)。

该对象嵌套在大小为n的列表的两个嵌套循环中,所以总体来说是O(n ^ 3)。