【发布时间】:2020-10-21 10:38:20
【问题描述】:
我想了解这两种解决方案在时间复杂度上的差异。 该任务无关紧要,但如果您对 here 感到好奇,请查看说明链接。
这是我的第一个解决方案。正确性得分为 100%,但性能得分为 0%:
def solution(s, p ,q):
dna = dict({'A': 1, 'C': 2, 'G': 3, 'T': 4})
result = []
for i in range(len(q)):
least = 4
for c in set(s[p[i] : q[i] + 1]):
if least > dna[c]: least = dna[c]
result.append(least)
return result
这是第二种解决方案。正确性和性能得分 100%:
def solution(s, p ,q):
result = []
for i in range(len(q)):
if 'A' in s[p[i]:q[i] + 1]: result.append(1)
elif 'C' in s[p[i]:q[i] + 1]: result.append(2)
elif 'G' in s[p[i]:q[i] + 1]: result.append(3)
else: result.append(4)
return list(result)
现在这就是我的看法。在这两种解决方案中,我都遍历了一系列 Q 长度,并且在每次迭代中,我都在对字符串的不同部分进行切片,长度在 1 到 100,000 之间。
这就是我感到困惑的地方,在每次迭代的第一个解决方案中,我将字符串的一部分切片并创建一个集合以删除所有重复项。该集合的长度可以在 1 到 4 之间,因此迭代它必须非常快。我注意到的是,我在每次迭代中只迭代一次。
在每次迭代的第二个解决方案中,我将字符串的一部分切片三遍并遍历它,在最坏的情况下,三遍,长度为 100,000。
那为什么第二种解决方案更快?第一个时间复杂度是O(n*m),第二个是O(n+m)怎么办?
我认为这是因为 in 和 for 运算符,但我在 JavaScript 中使用 indexOf 方法尝试了相同的第二个解决方案,它仍然获得 100% 的性能。但为什么?我可以理解,如果在 Python 中 in 和 for 运算符有不同的实现并且在幕后工作不同,但在 JS 中 indexOf 方法只是应用一个 for 循环。那么它与直接在我的函数中执行 for 循环不一样吗?这不应该是 O(n*m) 时间复杂度吗?
【问题讨论】:
-
只是一个简短的评论“集合的长度可以在 1 到 4 之间,因此迭代它必须非常快” 当然可以,但是需要的时间呢? 创建集合?
-
我知道创建它需要时间,但每次迭代只需执行一次。遍历一整段字符串 3 次不是慢很多吗?
-
在我看来,这两种解决方案都是 O(q * n)。通过将 As、Cs 和 Gs 的索引存储在一个数组中,您可以进行二等分以找到索引 x >= P[i] 并且如果 Q[i] >= x 对应的数组是最小因子,否则继续下一个数组的索引。这将是 O(n + q * logn)。
-
我理解主要思想,但我不熟悉“执行二等分”.. 我是一个菜鸟,我还在学习 :) 我试图对字符串进行迭代而不是 Q,我用 x >= P[i] 和 x
标签: python algorithm performance