我通常可以通过在Desmos上绘制图形来回答此类问题,但是我很难弄清楚如何表示这些图形以可视化陡度差异,尤其是当m趋于n且m超过n时。
出现这种情况的示例是“比较两个数组以查找第二个数组中的第一个数组是否有重复项”。这里,m
和n
是数组的长度。如果m和n相等,则对于嵌套循环成对比较解决方案,复杂度为n^2
。但是,如果它们不相等,那么复杂度图是否比n^2
更“差”?我似乎无法弄清楚如何绘制图形以进行检查,甚至无法数学表达。
答案 0 :(得分:1)
这完全取决于m
是什么。当我们在这里谈论时间复杂度时,甚至没有绘制图表,可以说当(m*n)
<O(n^2)
时,O m
比n
好。例如,m
可以是O(logn)
,O(n^(1/2))
等。
OP编辑了问题之后:
我将讨论compare two arrays to find if there are any duplicates from the first array in the second array
部分。
假设A
的大小为m
,B
的大小为n
。
vector<int> find_duplicates(vector<int> A, vector<int> B){
vector<int> duplicates;
unordered_map<int, int> frequency;
for(auto num: B){
frequency[num]++;
}
for(auto num: A){
if(frequency[num] > 0){
duplicates.push_back(num);
frequency[num]--;
}
}
return duplicates;
}
for(auto num: B){...}
具有时间复杂度O(n)
。 for(auto num: A){...}
具有时间复杂度O(m)
。但是m> n或m
在此解决方案O(max(m,n))
<O(m*n)
中。希望这能消除您的疑虑。
答案 1 :(得分:1)
n 和 m 是完全独立的变量。如果 m 可以用 n 表示,那么复杂度将纯粹用 n 表示。
自变量 n 和 m 的常见情况是定义两个任意大小的数组的长度。
将这些时间复杂度相互比较根本没有意义,因为它们是指互斥的问题类别。
使用您的示例, O(m * n)定义了一种可能的解决方案的复杂性
比较两个数组以查找第二个数组中的第一个数组是否有重复项
但是,两个数组的长度仍然是独立的,因此即使在特定情况下它们
因为每个可能的解决方案都必须对每个数组进行至少一次迭代,并且两个数组都没有恒定的长度,并且两个长度都不用另一个表示,所以对于上面的问题,其复杂性可以完全由下式定义: n 的术语,因此试图推断每种复杂性的相对效率没有任何意义。
答案 2 :(得分:1)
对于m
和n
的任何给定常数值,我们无法说出哪个更快。这是因为按照定义,Big-O仅在值趋于无穷大时才适用。因此,展望未来,我假设我们正在谈论当值趋于无穷大时会发生什么。
我们想知道何时O(m*n)
比O(n^2)
快。 Big-O的形式定义检查f(n) <= k.g(n)
或f(n)/g(n)
。无论哪种情况,从n > 0
开始,很容易看出我们可以从n
和m*n
中取消一个n^2
并得到同等的支票。
因此,现在我们想找出O(m)
的每个值超出某个点的时间O(n)
比m
快,即n
小于n
实际上,这与说m = o(n)
一样,这就是您的答案。注意:即little-O。
用不太抽象的术语来说,m
可以是n
“小于” n
(大于一个常数)的任何函数。举一些例子:
m = 1
有效。m = log n
有效。m = sqrt(n)
有效。m = n / 231689
不起作用(相差一个常数)。m = n - 9873054
不起作用(相差一个常数)。m = n^2
不起作用(m
增长更快)。