Algorithm 为什么是O(1)!=O(log(n))?对于n=[整数,长,…]

Algorithm 为什么是O(1)!=O(log(n))?对于n=[整数,长,…],algorithm,complexity-theory,big-o,Algorithm,Complexity Theory,Big O,例如,假设n=Integer.MAX_值或2^123,然后O(log(n))=32和123,因此是一个小整数。不是O(1)吗 有什么区别?我想,原因是O(1)是常数,但O(log(n))不是。还有其他想法吗?显然,如果您知道输入将始终具有固定数量的元素,那么算法将始终以恒定时间运行。Big-O表示法用于表示最坏情况下的运行时间,它描述了元素数量无限大时的限制。您要查看的是增长率。O(1)意味着根本没有增长。而O(logn)确实有增长。尽管增长很小,但仍然是增长。区别在于n不是固定不变的。Big-

例如,假设n=Integer.MAX_值或2^123,然后O(log(n))=32和123,因此是一个小整数。不是O(1)吗


有什么区别?我想,原因是O(1)是常数,但O(log(n))不是。还有其他想法吗?

显然,如果您知道输入将始终具有固定数量的元素,那么算法将始终以恒定时间运行。Big-O表示法用于表示最坏情况下的运行时间,它描述了元素数量无限大时的限制。

您要查看的是增长率。O(1)意味着根本没有增长。而O(logn)确实有增长。尽管增长很小,但仍然是增长。

区别在于
n
不是固定不变的。Big-O符号背后的思想是了解输入的大小如何影响运行时间(或内存使用)。因此,如果一个算法总是花费相同的时间,无论n=1还是n=Integer.MAX_值,我们都说它是
O(1)
。如果每次输入大小翻倍时,算法花费的时间延长了一个单位,那么我们说它是
O(logn)

编辑:为了回答你关于O(1)和O(logn)之间的区别的具体问题,我将给你一个例子。假设我们需要一个算法,可以在未排序的数组中找到min元素。一种方法是遍历每个元素并跟踪当前最小值。另一种方法是对数组排序,然后返回第一个元素

第一种算法是O(n),第二种算法是O(nlogn)。假设我们从16个元素的数组开始。第一个算法将在时间16内运行,第二个算法将在时间16*4内运行。如果我们把它增加到17,那么它就变成17和17*4。我们可以天真地说,第二个算法所用的时间是第一个算法的4倍(如果我们将logn组件视为常量)


但让我们看看当数组包含2^32个元素时会发生什么。现在,第一个算法需要2^32时间才能完成,而第二个算法需要32*2^32时间才能完成。它需要32倍的时间。是的,这是一个小小的区别,但仍然是一个区别。如果第一个算法需要1分钟,那么第二个算法将需要半个多小时

如果
n
在上面有界,那么涉及
n
的复杂度类就没有意义了。没有“当2^123接近无穷大时在极限内”这样的东西,除了一个古老的笑话“一个五角大楼近似一个圆,足够大的值为5”

通常,在分析代码的复杂性时,我们假设输入大小不受机器资源限制的限制,即使它是。这确实会导致
logn
发生一些稍微奇怪的事情,因为如果
n
必须适合固定大小的int类型,那么
logn
有一个相当小的界限,因此这个界限更可能有用/相关

所以有时候,我们在分析一个稍微理想化的算法版本,因为实际编写的代码不能接受任意大的输入

例如,您的平均快速排序在最坏的情况下正式使用Theta(logn)堆栈,显然,对于在分区的“小”端递归调用而在“大”端递归循环的相当常见的实现也是如此。但在32位机器上,您可以安排使用一个大约240字节的固定大小数组来存储“待办事项列表”,这可能比您基于正式使用O(1)堆栈的算法编写的其他函数要少。道德就是实现算法,复杂度不会告诉你任何关于小数字的事情,任何特定的数字都是“小”的


例如,如果要考虑边界,可以说对数组进行排序的代码是O(1)运行时间,因为数组的大小必须小于适合PC地址空间的大小,因此排序时间是有边界的。然而,如果你这样做了,你的CS作业就会失败,并且你不会向任何人提供任何有用的信息:-)

你的想法不够大。在计算机上运行的任何算法要么永远运行,要么在执行少量步骤后终止——因为计算机只是一个有限状态机,所以您不能编写运行任意时间然后终止的算法。根据这个论点,Big-O符号只是理论上的,在现实生活中的计算机程序中没有任何意义。即使是
O(2^n)
也会在
O(2^INT\u MAX)
处达到上限,这相当于
O(1)


但实际上,如果你知道常数因子,Big-O可以帮你解决这个问题。即使一个算法的上界是
O(logn)
,并且
n
可以有32位,这可能意味着一个请求需要1秒和32秒之间的差异。

如果将它称为
O(n^0)
,我想你会有更好的想法

它是一个缩放函数,取决于输入变量
N
。它是一个函数,而不是数字,您不应该为变量
N
假设任何数字


这就像你说一个函数
f(x)
是3,因为
f(100)=3
,这是错误的。它是一个函数,不是任何特定的数字。一个常量函数
f(x)=1
仍然是一个函数,它永远不会等于另一个函数
g(x)=N
,即
g(x)=f(x)
Big-O显示运行时间(或内存等)如何随着问题大小的变化而变化。 当问题的规模变大10倍时,O(n)解需要10倍的时间,O(log(n))解需要更长的时间,而O(1)解需要相同的时间:O(1)表示“变化与常数1一样快”,但常数不会变化


<>熟悉.< /p>

有一个原因,你为什么要离开O(n),并考虑放弃“O(log n)”。它们都是“常量”:fo