这是一个O(n)算法吗?

Is this technically an O(n) algorithm?

本文关键字:算法 一个      更新时间:2023-10-16

根据我对算法的理解,以下是技术上的线性解。

int max ( int * arr, size_t n )
{
    for (int k = 0; k < 100000000000000000000000000000; ++k)
        std::cout << rand(); // doesn't do anything useful   
    int largest = *arr; 
    for (int * offend = arr + n; arr != offend; ++arr)
        if (*arr > largest)
            largest = *arr;    
    return largest;
}

事实上,我可以添加尽可能多的垃圾,只要操作的数量相对于n线性增长,根据现代采访者,它被认为是一个"更好"的算法。对吗?

是的,它绝对会被认为是0 (n)。第一行是一个常量(非常大,但仍然是常量),所以它根本不影响渐近复杂度。

也就是说,根据一位不知道自己在说什么的采访者的说法,该算法只会被普遍认为比更理智的O(n log n)算法"更好"。任何关于算法复杂性的现实世界讨论,特别是在比较多个选项时,绝对应该包括渐近复杂性,但也应该包括所涉及的常量(乘法- 2n vs. 1000000n -和加法- n vs. n + 100000000),以及它将运行的上下文(例如:假设你正在通过你的算法运行一个googol项目:现在你的算法可能是更好的选择。)

如果我在面试中被问到这个问题,这就是我想说的话,而且很可能是面试官想听到的话。

没有,这不是O (n)。

如果你的编译器没有超过96位的扩展整型,它将被拒绝为病态。如果它确实编译(128位整型不是闻所未闻的),情况可能更糟…

由于有符号整数变量k溢出,该行为和复杂度都是未定义的。在许多相同的编译器上,这段代码永远不会终止,这使得它比复杂度为0 (nn!)的算法更糟糕……事实上,它也比《神奇的金钱机器》中看到的权力塔更糟糕。

如果您在面试中看到这段代码,它会很自然地引发关于正确性比性能更重要的讨论。