【发布时间】:2021-11-15 17:56:01
【问题描述】:
如果客户在某一天的消费金额大于或等于客户在过去几天的平均支出的 2 倍,他们会向客户发送有关潜在欺诈的通知。银行不会向客户发送任何通知,直到他们至少拥有前几天的交易数据。
给定过去的天数 d 和客户在 n 天期间的每日总支出,确定客户将收到通知的次数n 天。
我的代码可以解决问题,但是对于大型测试用例有时间限制。我的代码无法通过时间限制要求。我的代码实际上很短:
from statistics import median
first_multiple_input = input().rstrip().split()
n = int(first_multiple_input[0])
d = int(first_multiple_input[1])
expenditure = list(map(int, input().rstrip().split()))
count=0
for i in range(len(expenditure)-d):
if expenditure[d+i] >= 2*median(expenditure[i:d+i]) :
count+=1
print( count)
请指出造成延迟的原因以及如何改进。
帮助理解代码的小测试用例:
9 5 expenditure[] size n =9, d = 5
2 3 4 2 3 6 8 4 5 expenditure = [2, 3, 4, 2, 3, 6, 8, 4, 5]
【问题讨论】:
-
算法问题多于执行时间问题。我认为动态编程方法可以帮助你,虽然我可能是错的。最终,您将需要以某种方式进行更少的迭代。中值函数也可能很慢。时间限制是多少,什么时候失败?
-
@Wahalez,嗨,它需要 10 秒,我检查了小测试用例它是 '10.2016355999136353' 第二个没问题。例如,大型测试用例有 200000 名加速器,以及 10122 天。我正在通过谷歌寻找原因。我也怀疑中值函数是问题所在。
-
您应该分析您的脚本并查看它在哪里花费了大部分时间。见How can you profile a Python script?。我猜测耗时的部分可能是
for-loop 和中位数的重复计算。如果您查看函数的source code,您会发现它每次调用时都会对数据进行排序,这相对昂贵——因此以某种方式避免该步骤将是一个好策略。 -
谢谢@martineau,至少我知道原因,现在正在研究解决方案。这对我来说是一种新的问题。
-
基本上正在计算数据“滑动窗口”的中位数。对于非常大的数据集,可能值得为此“窗口”使用固定大小的
collections.deque,因为它已针对从其两端添加和删除元素进行了优化。
标签: python execution-time