对于m的哪个值(以n表示),O(m * n)优于O(n ^ 2)(为什么)?

时间:2019-07-08 03:59:41

标签: algorithm time-complexity

我通常可以通过在Desmos上绘制图形来回答此类问题,但是我很难弄清楚如何表示这些图形以可视化陡度差异,尤其是当m趋于n且m超过n时。

出现这种情况的示例是“比较两个数组以查找第二个数组中的第一个数组是否有重复项”。这里,mn是数组的长度。如果m和n相等,则对于嵌套循环成对比较解决方案,复杂度为n^2。但是,如果它们不相等,那么复杂度图是否比n^2更“差”?我似乎无法弄清楚如何绘制图形以进行检查,甚至无法数学表达。

3 个答案:

答案 0 :(得分:1)

这完全取决于m是什么。当我们在这里谈论时间复杂度时,甚至没有绘制图表,可以说当(m*n) <O(n^2)时,O mn好。例如,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的大小为mB的大小为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(max(m,n)) <O(m*n)中。希望这能消除您的疑虑。

答案 1 :(得分:1)

n m 是完全独立的变量。如果 m 可以用 n 表示,那么复杂度将纯粹用 n 表示。

自变量 n m 的常见情况是定义两个任意大小的数组的长度。

将这些时间复杂度相互比较根本没有意义,因为它们是指互斥的问题类别。

使用您的示例, O(m * n)定义了一种可能的解决方案的复杂性

  

比较两个数组以查找第二个数组中的第一个数组是否有重复项

但是,两个数组的长度仍然是独立的,因此即使在特定情况下它们 happen 相等,也不能声称算法现在为 O(n ^ 2)。除非在问题中明确指出它们共享相同的长度,否则 n m 仍然是独立变量。

因为每个可能的解决方案都必须对每个数组进行至少一次迭代,并且两个数组都没有恒定的长度,并且两个长度都不用另一个表示,所以对于上面的问题,其复杂性可以完全由下式定义: n 的术语,因此试图推断每种复杂性的相对效率没有任何意义。

答案 2 :(得分:1)

对于mn的任何给定常数值,我们无法说出哪个更快。这是因为按照定义,Big-O仅在值趋于无穷大时才适用。因此,展望未来,我假设我们正在谈论当值趋于无穷大时会发生什么。


我们想知道何时O(m*n)O(n^2)快。 Big-O的形式定义检查f(n) <= k.g(n)f(n)/g(n)。无论哪种情况,从n > 0开始,很容易看出我们可以从nm*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增长更快)。