繁体   English   中英

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

[英]Why is this O(N^3) and not O(N^4)?

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)吗?

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)并存储其值。

如果语句不是循环。

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

它嵌套在大小为n的列表的两个嵌套循环中,因此总体上为O(n ^ 3)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM