这个计算向量中值的最小差的函数的算法复杂度是多少?
Posted
技术标签:
【中文标题】这个计算向量中值的最小差的函数的算法复杂度是多少?【英文标题】:What is the algorithmic complexity of this function that calculates the minimum difference of values in a vector? 【发布时间】:2013-11-07 08:48:51 【问题描述】:我编写了一个函数,它接受一个整数向量,并返回两个元素之间的最小差异(即,彼此最近的元素的差异)。
我正在尝试计算算法的复杂性。第一个 for 循环遍历输入的所有元素(我称之为 N),这是线性复杂度:O(n)。内部 for 循环第一次迭代 N - 1,然后是 N - 2, N - 3, ... N - N + 2, N - N + 1, 0。所以我不认为这个算法是 O( n^2)。我的猜测是 O(N * log(N)),对吗?
#include <cstdlib>
#include <vector>
long int function(const std::vector<int> &Input)
long int MinimumDifference = -1;
for(size_t i = 0; i < Input.size(); i++)
for(size_t j = i + 1; j < Input.size(); j++)
long int Difference = abs(static_cast<long int>(Input[i] - Input[j]));
if(Difference < MinimumDifference || MinimumDifference < 0)
MinimumDifference = Difference;
return MinimumDifference;
编辑: 所以上面是O(n^2),认为我可以通过首先对列表进行排序来实现O(N * log(N))(使用std::sort,它有O(N * log(N))),并且然后只需遍历列表以找到最小的差异。
#include <cstdlib>
#include <vector>
£include <algorithm>
void function(const std::vector<int> &Input)
std::vector<int> SortedInput = Input;
std::sort (SortedInput.begin(), SortedInput.end());
long int MinimumDifference = -1;
for(size_t i = 0; i < SortedInput.size() - 1; i++)
long int Difference = abs(static_cast<long int>(SortedInput[i] - SortedInput[i + 1]));
if(Difference < MinimumDifference || MinimumDifference < 0)
MinimumDifference = Difference;
return MinimumDifference;
【问题讨论】:
注意,如果你想改进O,你可以先对列表进行排序,然后进行一次遍历以获得最小的差异。这可能会让你得到 O(nLog(n)) (取决于使用的排序算法)。 你必须意识到即使一个算法是O(n^2)
,这并不一定意味着有精确的n^2个操作要执行。相反,它代表c * n^2
,其中c
可以是任何正常数。在你的情况下,c=1/2
.
【参考方案1】:
一点代数运算告诉我们
(n-1) + (n-2) + ... + 1 = n * (n+1) / 2
= n^2 / 2 + O(n)
所以这个算法的复杂度确实是O(n^2)
【讨论】:
有趣的是,我会使用o(n^2)
(与此相比较小)而不是 O(n)(大小)。只是心态不同,但我同意答案(同时输入我的)
@Bruce:不过,混合使用 Big-O 和 little-o 符号是一种混淆人们的好方法。特别是对于那些字迹和我一样小的人。
AFAIK,n^2 + n = n^2 + o(n^2)
为lim(n/n^2) = lim(1/n) = 0
。如果f(n)=O(y(n)) + o(y(n))
然后f(n) = O(y(n))
。相反,如果f(n)=O(y(n)) + O(x(n))
,那么您必须比较 x 和 y 以查看哪个权重最大(在您的情况下这是微不足道的,因为比较 n^2 和 n 是直接的)......无论如何,g'd 回答和很抱歉评论垃圾邮件。
@Bruce:实际上,更严格的答案是使用θ(n^2)
,因为复杂性在n^2
上下之间。 f(n) in o(g(n))
的定义是对于每个真实的k > 0
,然后是|f(n)| < k . |g(n)|
,所以这里不准确。 wikipedia【参考方案2】:
不,你正在重叠两个“大致相同大小”的循环,你的复杂性是O(n^2/2)
= O(n^2)
为了说服自己,想想sum(i) for i in [0,n] = n.(n+1)/2 = O(n^2/2) = O(n^2)
这正是你在做的事情。
要做一些“新手的复杂性”,只需计算叠瓦循环的数量。如果他们在基本元素上迭代,则乘以n
,如果他们将问题复杂性降低一个顺序(将问题分成两半),则乘以log(n)
【讨论】:
以上是关于这个计算向量中值的最小差的函数的算法复杂度是多少?的主要内容,如果未能解决你的问题,请参考以下文章