这个计算向量中值的最小差的函数的算法复杂度是多少?

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 &gt; 0,然后是|f(n)| &lt; 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)

【讨论】:

以上是关于这个计算向量中值的最小差的函数的算法复杂度是多少?的主要内容,如果未能解决你的问题,请参考以下文章

如何找到向量的统计信息?最大值/最小值、众数、中值、平均值

vectorize向量化函数对DataFrame中值进行复杂运算

计算给出数组中最小标准差的子集

开平方根算法

该算法的比特成本时间复杂度是多少(Java 示例)?

最小和子向量的算法