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核及以上的算法。