我正在尝试解决 Codility 的Min Avg Two Slice问题。
我想出了以下代码:
def solution(S, P, Q):
weights = {'A': 1, 'C': 2, 'G': 3, 'T': 4}
retVal = []
for i in range(0, len(P)):
if P[i] == Q[i]:
retVal.append(weights[S[P[i]]])
else:
retVal.append(local_min(S, weights, P[i], Q[i]))
return retVal
minimums = {}
def local_min(S, weights, start, end):
minVal = weights[S[start]]
for i in range(start,end+1):
val = weights[S[i]]
if val == 1:
minimums[i] = 1
return 1
if val < minVal:
minVal = val
minimums[i] = minVal
return minVal
这在正确性方面效果很好,但是它具有时间复杂度,O(n*m)
因为我local_min
每次都重新计算而不重用任何结果。
我正在尝试使用prefix_sums
这里的算法来计算局部最小值,或者以某种方式使用minimums
对象记住计算出的最小值,并在随后的调用中重用它们local_min
。
我遇到的问题是 - 假设我们有以下数组:
[1, 13, 2, 8, 20, 5]
smallest values seen up to this point
我们可以计算如下数组:
对于范围0, 6
,它只是:
[1,1,1,1,1,1]
因为1,6
它将是:
[13, 2, 2, 2, 2]
对于2,6
:
[2, 2, 2, 2]
最后:
[8, 8, 8]
和
[20, 5]
我正在努力了解如何采用这种方法来计算smallest value in a given range
并降低我的解决方案的时间复杂度。
编辑:
我想出了以下解决方案,它在正确性和性能方面实现了 100% 的 Codility,并实现了时间复杂度O(n+m)
:
def solution(S, P, Q):
weights = {'A': 1, 'C': 2, 'G': 3, 'T': 4}
retVal = []
for i in range(0, len(P)):
if P[i] == Q[i]:
retVal.append(weights[S[P[i]]])
else:
if 'A' in S[P[i]:Q[i] + 1]:
retVal.append(1)
elif 'C' in S[P[i]:Q[i] + 1]:
retVal.append(2)
elif 'G' in S[P[i]:Q[i] + 1]:
retVal.append(3)
else:
retVal.append(4)
return retVal
不过,我仍然对此感到有些困惑-我的假设是该in
操作将采用的长度O(n)
在哪里,因此总体复杂性应该是长度在哪里-任何人都可以解释为什么实际上是复杂性n
S
O(n * m)
m
P
Q
O(n + m)