Python 是下面的函数O(n)时间和O(1)空间,其中n=| A |? def firstMissingPositive(自身,A): 最小值=1024*1024*1024 #最坏情况n操作 对于我来说,在一个: 如果i0: 最小=i 如果至少>1: 返回1 其他: #应为O(n) A_集=集(A) #最坏的情况再次发生 尽管如此: 最小+=1 如果至少不在_集合中: 回报最少

Python 是下面的函数O(n)时间和O(1)空间,其中n=| A |? def firstMissingPositive(自身,A): 最小值=1024*1024*1024 #最坏情况n操作 对于我来说,在一个: 如果i0: 最小=i 如果至少>1: 返回1 其他: #应为O(n) A_集=集(A) #最坏的情况再次发生 尽管如此: 最小+=1 如果至少不在_集合中: 回报最少,python,algorithm,time-complexity,Python,Algorithm,Time Complexity,我之所以问这个问题,是因为它对于给定的问题来说似乎太简单了,这里的大多数人可能都在Leetcode或类似的地方看到过这个问题。在Python的set或dict实现中有什么我不知道的吗?根据我的理解,查找应该是O(1),将列表转换为集合应该是O(n)。这不是O(1)空间,而是O(n)空间,因为您需要构建集合 至于时间,根据,设置安全壳需要O(n)最坏情况。因此,您的算法是O(n^2)。注意这是最坏的情况-集合包含的平均时间是O(1),因此算法的平均时间复杂度确实是O(n) 通过使用有序集合,您可以

我之所以问这个问题,是因为它对于给定的问题来说似乎太简单了,这里的大多数人可能都在Leetcode或类似的地方看到过这个问题。在Python的set或dict实现中有什么我不知道的吗?根据我的理解,查找应该是O(1),将列表转换为集合应该是O(n)。

这不是
O(1)
空间,而是
O(n)
空间,因为您需要构建集合

至于时间,根据,设置安全壳需要
O(n)
最坏情况。因此,您的算法是
O(n^2)
。注意这是最坏的情况-集合包含的平均时间是
O(1)
,因此算法的平均时间复杂度确实是
O(n)

通过使用有序集合,您可以将最坏情况下的时间降到
O(n log n)
,但平均时间也将是
O(n log n)

这不是
O(1)
空间,而是
O(n)
空间,因为您需要构建集合

至于时间,根据,设置安全壳需要
O(n)
最坏情况。因此,您的算法是
O(n^2)
。注意这是最坏的情况-集合包含的平均时间是
O(1)
,因此算法的平均时间复杂度确实是
O(n)


通过使用有序集,您可以将最坏情况降到
O(nlogn)
,但平均时间也将是
O(nlogn)

显然不是O(1)空间。是否可以将一个数组更改为哈希映射以克服该部分?我假设有,但没有仔细研究它。理论上可能是这样,但您的代码没有这样做,而且它可能不会有任何用处,因为您要处理的负载因子是1。显然不是O(1)空间。是否有可能将一个数组更改为hashmap以克服这一部分?我假设有,但没有仔细研究它。理论上可能是这样,但你的代码没有这样做,而且它可能不会有用,因为你要处理的负载因子是1。O(n)并不排除O(1),O(n^2)也不排除O(n)。集合包含通常被认为是O(1),至少是LeetCode(这是从哪里来的),所以在那里它将被算作O(n)时间。我认为你的意思是“平均”,而不是“摊销”。啊,这是有道理的,但是一组包含O(n)的最坏情况是什么?它不只是一个散列函数,将索引放入数组中,然后检查数组是否已初始化吗?@szhongren它确实是一个散列函数。但是散列函数并不完美,不同的对象可以有相同的散列(称为散列冲突,有一些技术可以处理它)。因此,在最坏的情况下,您可能会出现
n
哈希冲突(所有密钥都具有相同的哈希值),您必须对它们进行循环以找到合适的一个。然而,这可能永远不会发生,这就是为什么它的平均成本是
O(1)
。@StefanPochmann:啊,不,我的意思是设置的遏制时间是
O(1)
,但非摊销最坏情况时间是
O(n)
。所以你可以说这个算法是
O(n^2)
,或者是摊销
O(n)
(显然也可以写成)。但是它不是没有任何限制的
O(n)
,因为big-O表示最坏情况的时间,而不是平均时间。这只是平均情况O(1),通常的警告是“平均”是对可能的输入的均匀分布,而这些输入可能不能反映您实际收到的输入。此外,大O不只是在最坏的情况下出现。O(n)并不排除O(1),O(n^2)也不排除O(n)。集合包含通常被认为是O(1),至少是LeetCode(这是从哪里来的),所以在那里它将被算作O(n)时间。我认为你的意思是“平均”,而不是“摊销”。啊,这是有道理的,但是一组包含O(n)的最坏情况是什么?它不只是一个散列函数,将索引放入数组中,然后检查数组是否已初始化吗?@szhongren它确实是一个散列函数。但是散列函数并不完美,不同的对象可以有相同的散列(称为散列冲突,有一些技术可以处理它)。因此,在最坏的情况下,您可能会出现
n
哈希冲突(所有密钥都具有相同的哈希值),您必须对它们进行循环以找到合适的一个。然而,这可能永远不会发生,这就是为什么它的平均成本是
O(1)
。@StefanPochmann:啊,不,我的意思是设置的遏制时间是
O(1)
,但非摊销最坏情况时间是
O(n)
。所以你可以说这个算法是
O(n^2)
,或者是摊销
O(n)
(显然也可以写成)。但是它不是没有任何限制的
O(n)
,因为big-O表示最坏情况的时间,而不是平均时间。这只是平均情况O(1),通常的警告是“平均”是对可能的输入的均匀分布,而这些输入可能不能反映您实际收到的输入。此外,big-O不仅仅适用于最坏的情况。
def firstMissingPositive(self, A):
    least = 1024*1024*1024
    # worst case n ops
    for i in A:
        if i < least and i > 0:
            least = i
    if least > 1:
        return 1
    else:
        # should be O(n)
        A_set = set(A)
        # worst case n ops again
        while True:
            least += 1
            if least not in A_set:
                return least