[英]O(N) Time complexity for simple Python function
我刚刚参加了Codility演示测试。 在这里可以看到问题和我的答案 ,但是我也会在这里粘贴我的答案。 我的回复:
def solution(A):
# write your code in Python 2.7
retresult = 1; # the smallest integer we can return, if it is not in the array
A.sort()
for i in A:
if i > 0:
if i==retresult: retresult += 1 # increment the result since the current result exists in the array
elif i>retresult: break # we can go out of the loop since we found a bigger number than our current positive integer result
return retresult
我的问题是时间复杂度,希望您的回答能更好地理解。 问题要求预期的最坏情况下的时间复杂度为O(N) 。
我的函数是否具有O(N)时间复杂度? 我对数组进行排序的事实是否会增加复杂性?
编译报告(我的回答)
Detected time complexity:
O(N) or O(N * log(N))
那么,我的函数的复杂度是多少? 如果它是O(N * log(N)),那么当问题出现时,我该怎么做才能降低O(N)的复杂度?
非常感谢!
ps我关于时间复杂性的背景阅读来自这篇很棒的文章 。
编辑
遵循以下答复以及此处针对此问题描述的答案 ,我想在此方面介绍解决方案:
basicSolution的时间复杂度很高,因此对于此Codility测试不是正确的答案:
def basicSolution(A):
# 0(N*log(N) time complexity
retresult = 1; # the smallest integer we can return, if it is not in the array
A.sort()
for i in A:
if i > 0:
if i==retresult: retresult += 1 #increment the result since the current result exists in the array
elif i>retresult: break # we can go out of the loop since we found a bigger number than our current positive integer result
else:
continue; # negative numbers and 0 don't need any work
return retresult
hashSolution是我对上面文章“使用哈希”段落中描述的内容的看法。 由于我是Python的新手,请告诉我您是否对此代码进行了任何改进(尽管确实适用于我的测试用例),以及它的时间复杂度如何?
def hashSolution(A):
# 0(N) time complexity, I think? but requires 0(N) extra space (requirement states to use 0(N) space
table = {}
for i in A:
if i > 0:
table[i] = True # collision/duplicate will just overwrite
for i in range(1,100000+1): # the problem says that the array has a maximum of 100,000 integers
if not(table.get(i)): return i
return 1 # default
最后,实际的0(N)解决方案(O(n)时间和O(1)额外空间解决方案)让我难以理解。 我了解到负数/ 0值被推到数组的后面,然后我们得到的数组只是正值。 但是我不理解findMissingPositive函数-有人可以用Python代码/注释来描述吗? 也许有一个例子? 我一直在尝试用Python来解决它,但无法弄清楚:(
不会,因为您对A
排序。
Python list.sort()
函数使用Timsort (以Tim Peters命名),并且在最坏情况下的时间复杂度为O(NlogN)。
不必对输入进行排序,而必须对其进行迭代,并通过其他方法确定是否缺少任何整数。 我会使用一组range()
对象:
def solution(A):
expected = set(range(1, len(A) + 1))
for i in A:
expected.discard(i)
if not expected:
# all consecutive digits for len(A) were present, so next is missing
return len(A) + 1
return min(expected)
这是O(N); 我们创建了一个len(A)
(O(N)时间)的集合,然后遍历A
,从expected
删除元素(再次为O(N)时间,从集合中删除元素为O(1)),然后测试expected
为空(O(1)时间),最后得到expected
的最小元素(最多O(N)时间)。
因此,我们在上述函数中最多进行3个O(N)时间步长,使其成为O(N)解决方案。
这也符合存储要求; 所有使用的都是大小为N的集合。集合的开销较小,但始终小于N。
您发现的哈希解决方案基于相同的原理,除了它使用字典而不是集合。 请注意,字典值从未实际使用过,它们被设置为True
或不存在。 我将其重写为:
def hashSolution(A):
seen = {i for i in A if i > 0}
if not seen:
# there were no positive values, so 1 is the first missing.
return 1
for i in range(1, 10**5 + 1):
if i not in seen:
return i
# we can never get here because the inputs are limited to integers up to
# 10k. So either `seen` has a limited number of positive values below
# 10.000 or none at all.
如果A
中没有正整数,则上述方法避免一直循环到10.000。
mine和他们的区别在于,mine从一组期望的数字开始,而从A
组正值开始,从而反转存储和测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.