我总是一直在这个有点糊涂了,可能是由于我缺乏编译器的了解。但是让我们使用Python作为例子。如果我们有所谓的numlist号的一些大名单,并想摆脱任何重复的,我们可以在列表中,例如集(numlist)上使用集合运算符。作为回报,我们将有一组我们的数字的。此操作将尽我所知将在O(n)的时间来完成。虽然如果我创造我自己的算法来处理这个手术,我也为曾经希望绝对最好的是O(n ^ 2)。

我不明白的是,是什么让像集的内部操作()是如此之快那么外部语言算法。检查还需要做,不是吗?

有帮助吗?

解决方案

可以以任何语言为O(n)执行此操作,基本上为:

# Get min and max values O(n).

min = oldList[0]
max = oldList[0]
for i = 1 to oldList.size() - 1:
    if oldList[i] < min:
        min = oldList[i]
    if oldList[i] > max:
        max = oldList[i]

# Initialise boolean list O(n)

isInList = new boolean[max - min + 1]
for i = min to max:
    isInList[i] = false

# Change booleans for values in old list O(n)

for i = 0 to oldList.size() - 1:
    isInList[oldList[i] - min] = true

# Create new list from booleans O(n) (or O(1) based on integer range).

newList = []
for i = min to max:
    if isInList[i - min]:
        newList.append (i)

我在这里假设append是O(1)操作,这应该是除非实施者是脑死亡。因此,与k步各为O(n),则仍然有一个O(n)的操作。

无论步骤明确在你的代码,或者是否他们语言的幕后所做的一切是无关紧要的。否则可能要求的C qsort是一个操作和你现在有一个O(1)的圣杯排序例程: - )

由于很多人已经发现了,你可以经常权衡空间复杂度时间复杂度。例如,上面只适用,因为我们允许引进isInListnewList变量。如果这是不允许的,下一个最好的解决方案可以是排序列表(可能没有更好的为O(n log n)的),接着为O(n)(我认为)操作,以便移除重复。

一个极端的例子,则可以使用相同的额外空间方法进行排序的32位整数的任意数量的在O(n)的时间(与每个仅具有255或更少的重复说),提供可以分配约四十亿字节,用于存储所述计数

只要所有计数初始化为零,并通过您的列表中的每个位置上运行,增加基于该位置的数量计数。这是O(n)中。

然后开始在列表的开头,并通过计数阵列上运行,许多放置在列表中选择正确的值。这是O(1),与1为约四十亿当然,但仍恒定时间: - )

这也是O(1)空间复杂度,但一个非常大的“1”。典型地权衡不太,严重。

其他提示

您可以在Θ(n)平均时间使用哈希表的做到这一点。查找和插入在哈希表中Θ(1)平均。因此,你只需通过n项目和每一个检查运行,如果它是在哈希表已如果不插入该项目。

  

我不明白的是,是什么让像集的内部操作()是如此之快那么外部语言算法。检查还需要做,不是吗?

如果由语言实施者对由语言的用户正在执行实施的算法的复杂性渐进不改变。只要双方都在随机存取存储器模型图灵完整的语言来实现他们在各自实现将具有相同的渐进复杂相同的功能和算法。如果算法在理论上是O(f(n))如果在汇编语言,C#,或Python实现上仍然会O(f(n))不要紧。

在结合的算法的复杂性是完全无关的它是否被实现“内部”或“外部”

以列表,并把它转换为一组通过set()为O(n)。

这是因为set被作为散列集来实现。这意味着,要检查,如果事情是在设置或添加一些设定只需要O(1),固定时间。因此,为了从一个可迭代(例如像列表)一套,你刚开始与空集和逐个增加一个可迭代的元素。由于有n个元素且各插入花费O(1),转换一个可迭代的一组的总时间为O(n)。

要了解哈希实现是如何工作的,请参阅哈希表

关的手,我想不出如何做到这一点的O(n)的,但这里是很酷的事情:

^ 2和n N之间的差是大规模的sooo,相比于用于实现它的算法你执行它和python实现之间的差别是很小的。 N ^ 2总是大于O(n)的差,即使在n ^ 2之一是在C和O(n)的一个是在python。你不应该认为这种差异来自于你不是在一个低级语言写的事实。

这是说,如果你想实现你自己的,你可以做一个排序,然后删除的DUP。排序为n * LN(n)和在O删除的DUP(N)...

有两个问题在这里。

时间复杂度(其在大O表示法表示)的算法需要多长时间来对一组给定大小运行的正式测量。这是详细了解如何以及一个算法规模大于约绝对速度。

的算法的实际速度(比如,以毫秒为单位)是时间复杂度乘以一个常数(在理想世界)。

两个人可以实现带O的相同的去除重复算法的(的log(n)* n)的复杂性,但是,如果一个在Python写入它和其他在优化的C将其写入,则C程序会更快。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top