如何减少执行时间(Python)

时间:2019-08-04 16:46:13

标签: python optimization

我正在尝试解决此问题:https://www.hackerrank.com/tests/2h92ckdchlg/ (我的工作是计算在filterRanges的所有间隔中适合多少个频率值)

但是在执行10秒钟的代码后,我面临着“由于超时而终止”的问题。

我的解决方法是:

def countSignals(frequencies, ranges):
    ranges = [range(i[0], i[1] + 1) for i in ranges]
    return sum(1 if all(f in r for r in ranges) else 0 for f in frequencies)


if __name__ == '__main__':

    frequencies_count = int(input().strip())

    frequencies = []

    for _ in range(frequencies_count):
        frequencies_item = int(input().strip())
        frequencies.append(frequencies_item)

    filterRanges_rows = int(input().strip())
    filterRanges_columns = int(input().strip())

    filterRanges = []

    for _ in range(filterRanges_rows):
        filterRanges.append(list(map(int, input().rstrip().split())))

    result = countSignals(frequencies, filterRanges)

    print(result)

我只能编辑countSignal函数!

我的代码如何运行:

我收到一个数字,等于len(频率)。之后,我将获得构成频率列表的每个元素。然后,我收到len(filterRanges)和组成矩阵filterRanges的每个列表的尺寸。最后,我得到组成每个列表的值。

输入示例:

5 #-> len(frequencies)
20 #-> frequencies[0]
5 #-> frequencies[1]
6 #-> frequencies[2]
7 #-> frequencies[3]
12# -> frequencies[4]
3 #-> len(filterRanges) -> filterRanges is a matrix
2 #-> lenght of the lists that compose filterRanges
10 20 #-> filterRanges[0] = [10,20]
5 15 #-> filterRanges[1] = [5,15]
5 30 #-> filterRanges[2] = [5,30]

例如,在这种情况下,它将返回1,因为只有“ 12”适合所有间隔。

我已经使用此代码完成了15个测试中的12个,最后3个都出现了超时错误。如何优化我的代码,以便能够通过所有这些测试?

谢谢! :)

2 个答案:

答案 0 :(得分:0)

已编辑。 将以O(n + m)运行。只是合并重叠的间隔。

KeyVaultKeyResolver

答案 1 :(得分:0)

看你的例子:

frequencies = [20, 5, 6, 7, 12]
ranges = [[10,20], [5,15], [5,30]]

您要解决的问题是确定frequencies列表中有多少项目满足标准10 <= f <= 15,其中f是频率,10是最大频率范围的起始值,15是范围的最小终止值。您首先需要确定此条件检查的上限和下限。

lower_bound = None
upper_bound = None
for r in ranges:
    if lower_bound is not None:
        lower_bound = max(lower_bound, r[0])
    else:
        lower_bound = r[0]
    if upper_bound is not None:
        upper_bound = min(upper_bound, r[-1])
    else:
        upper_bound = r[-1]

现在,您可以遍历frequencies列表并计算满足条件的频率。在一种特殊情况下,下限可能大于上限,在这种情况下,没有解决方案,因此返回值应为0

count = 0
if (lower_bound < upper_bound):
    for f in frequencies:
        if lower_bound <= f <= upper_bound:
            count += 1

这可能就足够了,但是如果列表中有重复项,那么您将浪费时间检查它们-collections.Counter是解决此问题的好选择。

import collections
freq_counter = collections.Counter(frequencies)
count = 0
if (lower_bound < upper_bound):
    for f in freq_counter.keys():
        if lower_bound <= f <= upper_bound:
            count += freq_counter[f]

现在剩下的就是返回count的值。

return count