我今天正在审查有关算法的一些旧笔记,这让我想到了。
复杂性
O(1)
表示函数的执行时间与数据无关。
因此,假设我们有一个函数来添加数组中的所有元素。
int add(int[] array){
int sum =0;
for (int i=0;i<ARRAY_MAX_SIZE;i++){
sum= sum + (i<array.length?array[i]:0);
}
return sum;
}
其中ARRAY_MAX_SIZE
是数组的最大可能大小。我知道这段代码效率不高,我不想讨论这个问题。但是,运算符+
每次都被称为相同的金额时间,并且不受数据大小的影响。
这是否意味着此功能的复杂性为O(1)?
答案 0 :(得分:6)
是。 O(1)表示恒定时间,而不是快速/有效/最佳。
Big-O复杂性忽略了常量步骤的复杂性。分裂(慢)就像&#34;复杂&#34;作为增量(快)。
答案 1 :(得分:4)
实际答案是“它取决于”。
这里发生了两组不同的事情:
ARRAY_MAX_SIZE
次,你:
array.length
次,你:;
array[i]
ARRAY_MAX_SIZE - array.length
次,你:;
所以总运行时间是
t = k_1 * ARRAY_MAX_SIZE +
k_2 * n +
k_3 * (ARRAY_MAX_SIZE - n)
所以你看看k_2
和k_3
的比较方式。它们基本相同吗?然后它是O(1)
。是k_2 >> k_3
吗?然后它是O(n)
。
为什么k_2 >> k_3
?因为array[i]
正在访问内存,memory is comparatively very slow:
答案 2 :(得分:2)
唯一有趣的部分是array[i]
仅使用n
次。这意味着您添加一个操作来对数组进行处理,以使i
元素仅n
次。我不会这么算,但是这不可能成为O(n)
吗?只是扮演魔鬼的拥护者。
我认为这将是真正的O(1)
等价物。
int add(int[] array){
int sum =0;
int len = array.length;
for (int i=0;i<ARRAY_MAX_SIZE;i++){
sum= sum + array[i%len] & (i < len ? 0xFFFFFFFF : 0);
}
return sum;
}
答案 3 :(得分:-1)
如果你有一个最大的数组大小,那么复杂性将是O(1)
。但这还有其他后果。 array.length
需要小于ARRAY_MAX_SIZE,
,因此array.length
以常数为界,同时生成以下O(1)
:
for(int i=0; i<array.length; i++) {
sum = sum + array[i];
}
因此,我们通常会忽略对数组大小的任何限制,以便为算法的复杂性获得有用的结果。
这显然假设ARRAY_MAX_SIZE
是数组的最大可能大小(正如问题中定义的那样),而不是其他值。