This question引发了一些混淆和许多关于各种答案中提出的算法是O(1)还是O(n)的评论。
让我们用一个简单的例子来说明两个观点:
我们希望找到一个很长的
x
a * x + b = 0
,其中a
和b
已知,非空长。
x = - b / a
第二个算法是O(1)还是O(n)?
链接问题中提出的论点是:
c x O(1)
,其中c = 2^64
是常数。虽然我理解说它是O(1)的论点,但感觉反直觉。
ps:我添加了java,原始问题是Java,但这个问题与语言无关。
答案 0 :(得分:7)
只有存在变量N时,复杂性才有意义。因此,问题没有任何意义。如果问题是:
一个慢得多的算法将包括测试N个值范围内的每个可能值,平均值会慢大N倍。
第二个算法是O(1)还是O(N)?
然后答案是:这个算法是O(N)。
答案 1 :(得分:5)
Big O描述了算法的性能将如何缩放作为输入大小n缩放。换句话说,当您在更多输入数据上运行算法时。
在这种情况下,输入数据是固定大小,因此两种算法都是O(1),尽管具有不同的常数因子。
如果你用“n”表示数字中的位数(即你删除了它是64位长的限制),那么你可以分析给定的位大小n算法如何缩放。
在这种情况下,第一个仍然是O(1) (参见Qnan的评论),但第二个现在是O(2 ^ n)。< / p>
我强烈建议您观看MIT's "Introduction to Algorithms"课程的早期讲座。它们是对Big O(和Big Omega / Theta)的一个很好的解释,尽管我们很好地掌握了数学。
答案 2 :(得分:3)
检查每个可能的输入是解决方案中位数的O(2 ^ N)。当你使位数保持不变时,两个算法都是O(1),你知道需要检查多少解决方案。
答案 3 :(得分:1)
事实:您在计算机上实际运行的每个算法都是O(1),因为宇宙具有有限的计算能力(自大爆炸以来,有大量有限的原子和有限的秒数)。
这是事实,但不是一种考虑事物的非常有用的方式。当我们在实践中使用big-O时,我们通常假设所涉及的常数相对于渐近项是很小的,因为否则只给出渐近项并不能告诉你算法如何执行。这在实践中很有用,因为常量通常是“我使用数组还是哈希映射”,最多约为30x不同,输入为10 ^ 6或10 ^ 9,因此二次方之间的差异和线性算法比常数因子更重要。不遵守这一惯例的大O的讨论(如算法#2)毫无意义。
答案 4 :(得分:0)
无论a或b的值是多少,最坏的情况仍然是检查2 ^ 64或2 ^ 32或2 ^ somevalue值。该算法复杂度在O(2 ^ k)时间内,其中k是用于表示长值的位数,或者如果我们考虑a和b的值,则为O(1)时间。