Algorithm 计算算法复杂性-混淆

Algorithm 计算算法复杂性-混淆,algorithm,language-agnostic,time-complexity,Algorithm,Language Agnostic,Time Complexity,我有以下代码片段: sum = 0; for (i = 0; i < n; i++) for (j = 0; j < i; j++) sum++; sum=0; 对于(i=0;i

我有以下代码片段:

sum = 0;
for (i = 0; i < n; i++)
    for (j = 0; j < i; j++)
        sum++;
sum=0;
对于(i=0;i

复杂性将是
O(n^2)
,但是如果我想进一步挖掘内部循环的复杂性,那么它将是
(n(n-1))/2
(n-1)

常数与大O符号无关。

是的,O(n^2),但实际上是0+1+…+n-1=n(n-1)/2=O(n^2),绝对不是(n-1)

您计算的
(n(n-1)/2)
是代码的精确迭代次数。当被问及时间复杂度是否为大O时,您给出的估计值刚好足以表示所花费的时间

换句话说,您需要找到
n
最小的
,这样对于一些
k(k>0)
k*n^power
将大于确切的迭代次数。在您的情况下,
k
恰好是
1
power
恰好是
2
。然后,
O(n^power)
是您的时间复杂性

time = n*(n-1)/2
     = (n*n - n)/2
由于big-O表示法是一个上界,因此较小的阶项(-n)和常数因子(1/2)都被删除(因为它们对于表示时间上界并不重要)以产生big-O表示法,
O(n*n)
更好地称为
O(n^2)
首先,
(n-1)表示
(n-1)(n-2)…(2)(1)
。这显然不是你想要的

如果你计算实际的迭代次数,它是
0+1+2+…+(n-2)+(n-1)
。请注意,总和中有
n
项,我们可以将它们配对,使每对的平均值为
(n-1)/2
。(将最高值和最低值配对,第二高值和第二低值配对,等等)如果
n
为奇数,则剩下一个无法配对,但其值也方便地为
(n-1)/2
。因此,您有
n个
项,并且所有项的平均值为
(n-1)/2
,因此总总和为
n(n-1)/2


现在,对于大O表示法,我们有多少次迭代并不重要——我们只想知道当
n
非常大时的限制。请注意,我们的迭代次数可以写成
(1/2)n^2-(1/2)n
。对于非常大的
n
n^2
项远大于
n
项,因此我们去掉
n
项。这就给我们留下了
(1/2)n^2
,但是大O表示法的另一个规则是我们不关心常数因子,所以我们只写它是O(n^2)。

你可以有一个及时运行的算法

2222222222+4444444444444*n+999999999999999999999*n^2个步骤

它仍然是O(n^2)


找到比O更好的算法运行时间描述是一个公开的问题。

这是家庭作业吗?我将其标记为such.nops-我们在项目中进行,在计算解决方案的算法时,我有一个论点。所以我只是想确认一下,没有必要是n的幂。任何函数都可以,例如logn,2^n,n@胡安:它不仅不需要是
n
的一种力量,而且在某些情况下它是不可能的。例如,
n的增长速度比任何多项式都快。这实际上是不正确的。在n^2时间内运行的函数在O(n^3)中。(我说是在O(n^3)中,因为O(任何非零的东西)是一个简单的集合,有无限多个函数作为成员。)。Big-O所要求的是它是一个上界(更正式地说,我的意思是一些kn^3+c是一些常数k和c的上界)。大θ要求它既是上限又是下限。同意。我想到的第一件事就是回答。时间复杂性可以是任何其他表达式。我是从手边例子的角度来解释的——无意混淆提问者。我只想强调“最小功率”大于迭代的确切次数。另外,我提到的只是针对Big-O。我会编辑这篇文章。什么能把运行时间描述为“更好”?显然,我们可以更具体一些,比如这个算法发生在
f(n)
步骤中,或者这个算法在这样或那样的硬件上以每“n”个“X”毫秒的平均时间运行,但这并不一定会使这个描述“更好”。@Tim:嗯。。。在16核Mac上使用了一个正确的16线程排序,现在任何人都可以购买,并且看到它如何优于默认的Java单线程排序,我肯定会喜欢类似“O(n log n)/nb CPU”符号之类的东西。当n接近无穷大时,不会改变任何“上界”,但对于大多数实际用途,我们可能需要一些“更好”的东西,因为我们正在进入一个越来越并行的世界,而big-O根本不会将其切割为区分单线程算法和可扩展到16核及以上的算法。