问题是 *从1索引的零数组和一个操作列表开始,对于每个操作,在两个给定索引(包括两个索引)之间为每个数组元素添加一个值。完成所有操作后,返回数组中的最大值。 *
这是我的代码
def arrayManipulation(n, queries):
li = [0] * n
for query in queries:
a, b, c = map(int, [query[0], query[1], query[2]])
for i in range(a-1, b):
li[i] += c
return max(li)
这是行之有效的代码
def arrayManipulation(n, queries):
N, M = n, len(queries)
li = [0] * n
for i in range(M):
a, b, k = map(int, [queries[i][0], queries[i][1], queries[i][2]])
li[a-1] += k
try:
li[b] -= k
except:
pass
t = li[0]
for i in range(1, N):
li[i] += li[i-1]
if(li[i] > t):
t = li[i]
return t
我的代码在某些测试用例中给出了超时错误
答案 0 :(得分:0)
第一个实现可能需要太多时间来运行n
和queries
的某些选择的原因,而第二个实现对于相同的输入可能会更快,原因是这两个函数具有不同的computational complexity。
请考虑n
的一千万(n = 10**7
)值,以及一个queries
列表,其中包含大小可比(或等于)n
的范围,例如为queries = [(1, 10**7, 42)]*10
。
对于该输入,第一个实现将执行li[i] += c
行(10* 10 ** 7 = 10**8
)次,这可能会引起注意(运行可能需要几秒钟)。想象一下,对于更高的n
值和queries
长度,该乘积将变得更大。
作为n
和len(queries)
的函数,按数量级的操作数将为:n*len(queries)
。
相反,第二个函数经过优化,因此没有嵌套循环。
第一个循环内的操作:
for i in range(M):
a, b, k = map(int, [queries[i][0], queries[i][1], queries[i][2]])
li[a-1] += k
try:
li[b] -= k
except:
pass
预计运行M
次(即len(queries)
)。
第二个循环中的操作:
for i in range(1, N):
li[i] += li[i-1]
if(li[i] > t):
t = li[i]
将运行N
次(等于n
)。
因此,根据幅度n
和len(query)
的函数,第二个函数中的操作数将为:len(query) + n
。
例如,对于10个查询且n为10 ** 7,循环迭代将为10 + 10**7 ~= 10**7
。因此,那里没有乘法,并且该函数的运行速度比第一个实现要快。
您可以自己查看。首先,将第一个功能保存在名为solve1.py
的文件中,将第二个功能保存在solve2.py
中。然后在终端中运行以下命令:
运行第一个:
time python3 -c 'from solve1 import arrayManipulation;print(arrayManipulation(10000000, [(1, 10000000, 42)]*10))'
运行第二个:
time python3 -c 'from solve2 import arrayManipulation;print(arrayManipulation(10000000, [(1, 10000000, 42)]*10))'
在我的机器上,第一个大约需要8秒,而第二个大约需要1.8秒,这确认了第二个功能随着输入的增加而更快。