[英]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.