求和 O(1)+O(2)+ .... +O(n)
的结果是什么?
我曾在某处看到过它的解法,写着:
O(n(n+1) / 2) = O(n^2)
但是我对它不满意,因为O(1) = O(2) = 常数
,所以在我看来,它只能评估为O(n)
。 我在Cormen的书中也看到过这一点:
Σ(i=1 to n) O(i)
以上表达式只有一个匿名函数。这个函数与 O(1) + O(2) + ... + O(n)
不同,后者没有清晰的解释。
求和 O(1)+O(2)+ .... +O(n)
的结果是什么?
我曾在某处看到过它的解法,写着:
O(n(n+1) / 2) = O(n^2)
但是我对它不满意,因为O(1) = O(2) = 常数
,所以在我看来,它只能评估为O(n)
。 我在Cormen的书中也看到过这一点:
Σ(i=1 to n) O(i)
以上表达式只有一个匿名函数。这个函数与 O(1) + O(2) + ... + O(n)
不同,后者没有清晰的解释。
O(。)
产生一个集合,而不是一个值。“常数”本身并不存在。 - user824425n
不再被视为表示输入大小的参数,而是作为一个基数常量。因此,你实际上拥有一个可数无限的扩展系列,每个输入大小对应一个扩展,这并不是描述复杂度的好工具。然而,你仍然可以正式地操作大O符号背后的定义。 - collapsarO(.)
的参数实际上是一个函数,而另一个函数可以在该集合中。应该写成O(n :> n)
(n
映射到n
),而不是O(n)
,但为了方便起见,这种绑定是隐含的。严格来说,如果您已经将n
绑定到一个值并编写O(n)
,则您拥有O(1)
的子集(更正式地,O(x :> 1)
)。我看到过很多次对此解释不够准确(甚至错误),常常让我的同学感到困惑。我认为TAOCP没有不同的解释,只是不够精确。 - user824425O(.)
,有许多解释,有些精确,有些简短。这个问题需要一个非常精确的 O(.)
定义,TAOCP 没有给出(或者你引述不正确)。 (此外,我的解释受函数式编程的影响很大。) - user824425a_i * i <= f_i(x) <= b_i * i; x > X_i
对于一些正常数 a_i, b_i
和足够大的 X_i
,令 X = max_i ( X_i )
并对 n
个不等式求和,得到:
sum_i=1..n ( a_i * i ) <= sum_i=1..n ( f_i(x) ) <= sum_i=1..n ( b_i * i )
sum_i=1..n ( min(a_i) * i ) <= sum_i=1..n ( a_i * i )
sum_i=1..n ( b_i * i ) <= sum_i=1..n ( max(b_i) * i )
min(a_i) * 0.5*(n(n-1)) <= sum_i=1..n ( f_i(x) ) <= max(b_i) * 0.5*(n(n-1))
<=> A * (n(n-1)) <= sum_i=1..n ( f_i(x) ) <= B *(n(n-1))
O(n^2)
。当然,O(1)和O(2)是常数,所以我们可以忽略它们。但是O(n/2)是常数吗?我想不是。因此,尝试(在你的作业中)仅计算元素的后一半:
O(n/2) + O(n/2+1) + ... O(n) = ??
你会想出 O(n^2)
:)
有一个技巧可以找到这个公式,真的不难。
你有:
1 + 2 + 3 + 4 + .... + n如果你把这个列表数两次(一次从低到高排序,一次从高到低排序),你会得到两倍的结果。
((1 + 2 + 3 + 4 + ... + n) + (n + (n - 1) + (n - 2) ... + 2 + 1)) / 2
这与下面的公式相同:
((1 + n) + (2 + n - 1) + (3 + n - 2) + ... + (n + 1)) / 2
而这是:
((n + 1) * n) / 2
或者我们用O(n²)表示。