Time complexity 比较O(n&x2B;m)和O(max(n,m))的复杂度

Time complexity 比较O(n&x2B;m)和O(max(n,m))的复杂度,time-complexity,big-o,Time Complexity,Big O,我今天有个工作面试。被问及std:set\u交叉点的复杂性。我在回答时提到了这一点 O(n+m) 等于: O(最大值(n,m)) 有人告诉我这是不正确的。我试图证明与以下内容等价,但没有成功: O(0.5*(n+m))≤ O(最大值(n,m))≤ O(n+m) 我的问题是:我真的错了吗?对于所有的m,n≥ 0最大值(m,n)是有效的≤ m+n→ O(m+n)和m+n中的最大值(m,n)≤ 2max(m,n)→ O中的m+n(最大值(m,n)) 因此O(max(m,n))=O(m+n) 附录:

我今天有个工作面试。被问及std:set\u交叉点的复杂性。我在回答时提到了这一点

O(n+m)

等于:

O(最大值(n,m))

有人告诉我这是不正确的。我试图证明与以下内容等价,但没有成功:

O(0.5*(n+m))≤ O(最大值(n,m))≤ O(n+m)

我的问题是:我真的错了吗?

对于所有的m,n≥ 0最大值(m,n)是有效的≤ m+n→ O(m+n)和m+n中的最大值(m,n)≤ 2max(m,n)→ O中的m+n(最大值(m,n))

因此O(max(m,n))=O(m+n)


附录:如果f属于O(m+n),则存在常数D>0,对于足够大的m和n,f(n,m)你完全正确地认为O(n+m)等于O(max(n,m)),更精确地说,我们可以证明Θ(n+m)=Θ(max(n,m),它更严密,可以证明你的句子。数学证明是(对于大O和Θ)非常简单,易于理解,具有常识。因此,由于我们有一个
数学证明
,这是一种表达某事的方式,但定义更明确、更严格,而且
不会留下任何歧义

虽然你被(错误地)告知这是不正确的,因为如果我们想要非常精确,这不是合适的数学方法来表达最大值(m,n)的顺序与m+n相同。你使用了“等于”这个词来指大O符号,但大O符号的定义是什么

它被称为
集合
。说max(n+m)属于O(m+n)是 最正确的方法,反之亦然,m+n属于O(max(m,n))。在大O中 符号通常被用来表示m+n=O(max(n,m))

造成的问题是,你没有尝试引用函数的顺序,比如f是O(g),但是你尝试比较集合O(f)和O(g)。但是证明两个无穷集合相等并不容易(这可能会让面试官感到困惑)

当集合A和B包含相同的元素时,我们可以说它们是相同的(或相等的)(我们不尝试比较,而是引用它们包含的元素,因此它们必须是有限的)。当谈论大O集合时,甚至连识别都不容易应用

F的大O用来表示我们正在讨论的集合 包含阶数大于或等于F的所有函数。有多少个 有什么功能

当两个不同的集合在一起时,你怎么能说它们是相同的(或相等的) 无限,其实没那么简单

还有一件事,我们说过这些函数有相同的阶数,这在数学上是绝对正确的,但是当你尝试优化算法时,你可能需要考虑一些低阶因子,然后它们可能会给出稍微不同的结果,但渐近行为被证明是相同的

结论

正如你在(每所大学的所有cs课程或每本算法书中)读到的那样,大O/θ/Ω/ω/ο符号
帮助我们比较函数
并找到它们的增长顺序,而不是函数集,这就是为什么你被告知自己错了。虽然很容易说O(n^2)是O(n)的子集比较无限很难判断两个集合是否相同。Cantor致力于对无限集合进行分类,例如,我们知道自然数是可数无限的,实数是不可数无限的,所以即使两者都是无限的,实数也比自然数多。当对无限集合进行排序和分类,这更多的是一种数学研究,而不是一种比较函数的方法


更新

你可以简单地证明O(n+m)等于O(max(n,m)):

对于属于O(n+m)的每个函数F,这意味着存在常数c和k,例如:

 F <= c(n+m) for every n>=k and m>=k
 F <= c*max(n+m) for every n>=k and m>=k
F=k和m>=k
然后还有:

 F <= c(n+m)<= 2c*max(n,m) 

F我们将通过严格的Big-O分析证明,如果您在分析中选择了一个可能的增长参数,您确实是正确的。然而,这并不一定意味着面试官的观点是错误的,而是他/她对增长参数的选择不同。他/她提示您的答案完全不正确然而,ct是有问题的:您可能只是使用了两种稍有不同的方法来分析
std::set_intersection
的渐进复杂性,这两种方法都导致了算法在线性时间内运行的普遍共识


准备工作 让我们先看看CPPFreference(强调我的)处的
std::set_交叉点的引用

参数

last1
last1
-要检查的第一个元素范围

first2
last2
-要检查的第二个元素范围

复杂性

最多
2·(N1+N2-1)
比较,其中

N1 = std::distance(first1, last1)
N2 = std::distance(first2, last2)
其本身自然是线性的(最坏情况:无随机访问)

std::距离

返回
first
last
之间的元素数

我们将继续简要回顾Big-O表示法的基本原理


大O记号 我们松散地陈述了函数或算法的定义
f
位于
O(g(n))
(为了挑剔,
O(g(n))
是一组函数,因此
f∈ O(…)
,而不是常用的
f(n)∈ O(…)

如果函数
f
位于
O(g(n))
,则
c·g(n)
是一个上限 约束于
f(n)
,对于一些非负常数
c
,使得
f(n)≤
 F <= c*max(n+m) for every n>=k and m>=k
F <= c*max(n+m)<=2c(m+n) for every n>=k and m>=k
N1 = std::distance(first1, last1)
N2 = std::distance(first2, last2)
f(n) ≤ c · g(n), for all n ≥ n0,                                (+)
h(n, m) = 2 · (m + n - 1)
f(n) = 2 · (n + n - 1) = 4n - 2 > h(n,m)                         (*)
g(n) = n
f(n) = 4n - 2 < 4n = 4 · g(n)
f(n) < 4 · g(n) = c · g(n), for all n ≥ n0,                      (**) 
f ∈ O(g(n)) = O(n)
h ∈ O(g(n)) = O(n), assuming n > m                               (i)
h ∈ O(g(m)) = O(m), assuming m > n                                (ii)
O(max(m, n))