[英]For an algorithm with a time complexity of O(N+M), if M is always less than N, can we say the time complexity will be O(N)?
[英]O(N+M) time complexity
我正在解决一些给定目标时间复杂度和空间复杂度的练习问题。 其中之一给出了 O(N+M) 的目标时间复杂度。 我对 O(N+M) 算法外观的直觉有一些麻烦。 有没有人有这样的算法的例子或者可以清楚地解释它? 我试图想到的每个例子对我来说似乎都是 O(N*M)。
O(m+n)
算法的一个简单示例:
int sum(int[] nArr, int[] mArr) {
int sum = 0;
for(int i : nArr) {
sum += i;
}
for(int i : mArr) {
sum += i;
}
return sum;
}
要计算总和,您需要遍历nArr
所有元素(大小为n
)和mArr
所有元素(大小为m
),因此总体复杂度为O(m+n)
O(n + m) 算法的快速简单示例:
for (i = 0; i < n; i++)
{
// do something but don't loop or invoke recursive functions
// only constant O(c) complexity is allowed: a simple series of commands
}
for (i = 0; i < m; i++)
{
// idem
}
添加时复杂性是可交换的 (O(n + m) == O(m + n)) 这意味着您可以在不影响复杂性的情况下反转两个for()
。 显然,在算法层面上,倒置的可能不等同于直的。
作为额外的帮助,这里有一个 O(n * m) 算法的例子:
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
// do something but don't loop or invoke recursive functions
// only constant O(c) complexity is allowed: a simple series of commands
}
}
同样,您可以在不影响复杂性的情况下将内部与外部循环反转(O(n * m)== O(m * n))。 同样明显的考虑也适用。
您可以放入for()
主体的限制是因为大 o 表示法限制了上限。 如果它是一个下限(小 o 符号),您可能已经放入了更复杂的东西,但它永远不会低于这个数字。
所以,为了扩展其他的回复,我会尝试添加一个此类问题的示例,以帮助您理解:
例如,对 2 个向量的元素求和可以在 O(M+N) 中完成,但可以认为是 O(N)(假设 N>M)或 O(M)(如果 M>N)。
以上所有答案说明了 O(n+m) 是如何工作的,但我想通过了解 O(n m)、O(n+m) 和 O(n m)之间的区别从不同的角度来看待它主要区别是当 n 数乘以 m 数时,这意味着 n 将发生 m 次或将尝试 m 次,例如,下面的代码是 O(n*m) 因为 n 将发生 m 次 n次
for(int i=0; i < n;i++){
for(int j=0; j < m;j++){
//some_code
}
}
这个问题的直觉是你有两个唯一的变量n
和m
。 现在想象这两个独特的变量独立增加,接近无穷大。
如果这是一个 O(n) 问题(即 BIG-O),则该问题复杂性的向上边界至少是线性的。 你可以说O(n) = n^2
。 但是当n
(输入)接近无限时,O(n) 问题甚至永远不会接近n^2
限制。
同样, m
的行为将是相同的。 O(m)
可以是m^2
。 但更准确的说法是O(m) = m
。 这两个问题的复杂性是线性的。
现在,如果你只做O(n+m)
,那真的是n^2
吗? 不应该。 即使n=m
,总和也会是2n
或2m
。 这个问题的复杂性仍然是线性的,因为输出的大小仍然与输入n
和m
成正比。 因此,这个问题最准确的答案是O(n+m) = n+m
。
一个具有启发意义的例子是采用两个大小为 M 和 N 的排序数组,并输出一个包含所有这些元素的新排序数组。 这是归并排序的基础,将进行 O(M+N) 次比较。
你可以在任何地方找到一个例子或自己做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.