【问题标题】:Please tell me why my code timeouts while this code runs well?请告诉我为什么我的代码在此代码运行良好时会超时?
【发布时间】:2019-03-03 11:37:16
【问题描述】:

问题是 *从 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

我的代码在某些测试用例中出现超时错误

【问题讨论】:

  • 欢迎来到 StackOverflow。不幸的是,您的问题描述不完整。请告诉我们输入的数据格式(尤其是queries)、该输入的限制、一些示例输入以及该输入所需的输出。阅读并关注How to create a Minimal, Complete, and Verifiable example。如果您提供了导致代码超时的测试用例之一,这将特别有帮助(但我知道这可能是不可能的)。
  • 你确定 n 总是 >= 比倒数第二行中的 i
  • 静态数组索引值太多了,你也需要重构你的代码和逻辑
  • for i in range(a-1, b): li[i] += c 将此更改为 for i in (a-1, b): li[i] += c 您的代码将起作用
  • queries 的一些示例值可以帮助人们回答您的问题。

标签: python arrays algorithm


【解决方案1】:

对于nqueries 的某些选择,第一个实现可能需要太多时间来运行,而对于相同的输入,第二个实现可能更快,这是因为这两个函数有不同的computational complexity .

考虑一千万的 n 值 (n = 10**7),以及一个包含大小与 n 相当(或等于)的范围的 queries 列表,例如 queries = [(1, 10**7, 42)]*10

首次实施

对于该输入,第一个实现将执行 (li[i] += c) 10* 10 ** 7 = 10**8 行次,这可能会变得很明显(运行可能需要几秒钟)。想象一下,对于更大的n 值和queries 的长度,该乘积将变得更大。

作为nlen(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)。

因此,第二个函数中的操作数,按数量级,作为nlen(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 秒,这证实了第二个函数随着输入的增大而变得更快。

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多