大O符号O(n)和小O符号O(n)的区别是什么?
f∈O(g)表示
对于至少一个常数k > 0,你可以找到一个常数a,使得不等式0 <= f(x) <= k g(x)对所有x > a成立。
注意,O(g)是满足这个条件的所有函数的集合。
F∈o(g)表示
对于每一个常数k > 0,你可以找到一个常数a,使得不等式0 <= f(x) < k g(x)对所有x > a成立。
同样,注意o(g)是一个集合。
在Big-O中,你只需要找到一个特定的乘数k,它的不等式大于某个最小值x。
在Little-o中,必须有一个最小x,在这个x之后,不管k有多小,不等式都成立,只要它不为负或零。
这两个都描述了上界,尽管有点违反直觉,但Little-o是更有力的表述。如果f∈o(g),则f和g的增长率之间的差距要比f∈o(g)大得多。
这种差异的一个例子是:f∈O(f)为真,但f∈O(f)为假。因此,Big-O可以理解为“f∈O(g)表示f的渐近增长不快于g”,而“f∈O(g)表示f的渐近增长严格慢于g”。就像<=和<。
更具体地说,如果g(x)的值是f(x)的值的常数倍,则f∈O(g)为真。这就是为什么在使用大o符号时可以省略常量。
然而,要使f∈o(g)为真,则g的公式中必须包含x的更高次幂,因此f(x)和g(x)之间的相对间隔实际上必须随着x的增大而增大。
使用纯数学例子(而不是参考算法):
以下是对Big-O是正确的,但如果使用little-o就不正确了:
x² ∈ O(x²) x² ∈ O(x² + x) x² ∈ O(200 * x²)
以下是适用于little-o的情况:
X²∈o(X³) X²∈o(X !) Ln (x)∈o(x)
注意,如果f∈o(g),这意味着f∈o(g)。例如x²∈o(x³),那么x²∈o(x³)也是成立的,(同样,考虑o为<=,o为<)
大o之于小o,就像≤之于<。Big-O是包容性的上界,而little-o是严格的上界。
例如,函数f(n) = 3n为:
O(n²)O(n²)O(n) 不是O(lgn) O(lgn)或O(n)
类似地,数字1是:
≤2,< 2,和≤1 不是≤0,< 0,或者< 1
下面是一个表格,展示了大致的想法:
(注:该表是一个很好的指南,但其极限定义应根据上极限而不是正常极限。例如,3 + (n mod 2)永远在3和4之间振荡。它在O(1),尽管没有正常的限制,因为它仍然有一个lim sup: 4。)
我建议大家记住大o符号是如何转化为渐近比较的。比较更容易记住,但不太灵活,因为你不能说nO(1) = P。
我发现当我不能从概念上理解某件事情时,思考为什么人们会使用X有助于理解X(并不是说你没有尝试过,我只是在铺垫)。
你知道的东西:一种常用的算法分类方法是通过运行时,通过引用算法的大复杂度,你可以很好地估计哪个是“更好的”——哪个在O中有“最小的”函数!即使在现实世界中,O(N)也比O(N²)“更好”,除非有一些愚蠢的东西,比如超大质量常数之类的。
假设有某种算法在O(N)范围内运行。不错吧?但假设你(你这个聪明的人)提出了一个算法,在O(N⁄loglogloglogN)中运行。耶!它的速度!但是当你写论文的时候,你会觉得一遍又一遍地写这个很傻。你写一次,你可以说"在这篇论文中,我证明了算法X,之前在O(N)时间内可计算,实际上在O(N)时间内也可计算"
因此,每个人都知道你的算法更快——快多少还不清楚,但他们知道它更快。从理论上讲。:)
大o符号有一个同伴叫做小o符号。大o符号表示一个函数和另一个函数一样是渐近的。为了说明一个函数渐进地小于另一个函数,我们使用小o符号。大o和小o符号之间的差异类似于<=(小于等于)和<(小于)之间的差异。
推荐文章
- 如何计算圆周长上的一点?
- 从整数流中找到运行中位数
- 在日历应用程序中建模重复事件的最佳方法是什么?
- 在任何情况下,您更喜欢高大o时间复杂度算法而不是低大o时间复杂度算法吗?
- 如何使用JavaScript比较软件版本号?数量(只)
- 在常数平摊时间O(1)中将一个对象追加到R中的列表?
- 跳跃表vs.二叉搜索树
- 如何使四舍五入百分比加起来为100%
- 是否有可能得到一个函数的所有参数作为单一对象内的函数?
- LL和LR解析之间的区别是什么?
- log(n!) = Θ(n·log(n))?
- C语言中位反转的高效算法(从MSB->LSB到LSB->MSB)
- 递归还是迭代?
- 两个长度不等的表之间的排列
- 给出一个图像来表示和解决一个迷宫