【问题标题】:How to improve the run time of a python code如何提高python代码的运行时间
【发布时间】:2017-01-27 17:52:29
【问题描述】:

我正在尝试从在线编码网站解决以下问题。

问题: Fredo 非常擅长处理大量数字。因此,一旦他的朋友宙斯给了他一个包含 N 个数字的数组,然后是他必须回答的 Q 个问题。在每个查询中,他定义了查询的类型和 Fredo 必须回答的数字 f。每个查询有以下两种类型: 类型 0:对于这个查询,Fredo 必须回答数组中的第一个数字(从索引 0 开始),使其频率至少等于 f。 类型 1:对于这个查询,Fredo 必须回答数组中的第一个数字,使得频率正好等于 f。 现在,弗雷多回答了他所有的疑问,但现在宙斯想象他应该如何验证它们。因此,他要求您为此编写代码。 注意:如果没有数字是查询的答案,则输出 0。 使用快速 I/O。

输入: 输入的第一行包含 N ,数组的大小 下一行包含 N 个空格分隔的整数。 下一行包含 Q,表示查询的数量。 然后跟随 Q 行,每行有两个整数 type 和 f,表示查询的类型和您必须回答查询的频率。

输出: 您必须在单独的行中打印每个查询的答案。

输入约束:

1≤N≤106

1≤A[i]≤1018

1≤Q≤106

0≤类型≤1

1≤f≤1018

示例输入

6

1 2 2 1 2 3

5

0 1

0 2

1 2

1 3

0 3

样本输出

1

1

1

2

2

解决方案: 这是我尝试过的解决方案

from collections import Counter
import sys
tokenizedInput = sys.stdin.read().split()
t = int(tokenizedInput[0])
a = []
for i in range(t):
    s = int(tokenizedInput[i+1])
    a.append(s)
collection = Counter(a)
key = collection.keys()
value = collection.values()
q = int(tokenizedInput[i+2])
k = i+2
for j in range(q):
    query = int(tokenizedInput[k+2*j+1])
    f = int(tokenizedInput[k+2*j+2])
    for w in range(t):
        index = key.index(a[w])
        if query == 0:
            if value[index] >= f:
                print a[w]
                break
        else:
            if value[index] == f:
                print a[w]
                break
        if w == t-1:
            print 0

此代码运行正常,并为较小的测试用例提供正确的输出,但在较大的测试用例上超过了时间限制。有人可以建议可以对此代码进行哪些改进以提高速度。

【问题讨论】:

  • 这个属于codereview.stackexchange.com
  • 尝试使用this method自己弄清楚。
  • 我知道我们可以使用 strace 找到每一行的运行时间,但我不确定如何使用它。如果你能详细说明一下,我会很高兴

标签: python performance for-loop runtime


【解决方案1】:

一些建议:将tokenizedInputint() 转换完成并排除在外,而不是在循环中反复调用int();像collection 这样的字典非常有效,不要通过提取键和值来猜测它,按预期使用它;在循环之前预先计算你可以做的任何事情;简化,简化,简化。

我已经按照上面的建议重新编写了您的代码,并进行了其他调整,看看它是否对您有意义并在时限内执行练习:

import sys
from collections import Counter

tokenizedInput = map(int, sys.stdin.read().split())

N = tokenizedInput[0]

array = tokenizedInput[1:N + 1]

collection = Counter(array)

Q = tokenizedInput[N + 1]

k = N + 2

for j in range(Q):
    offset = 2 * j + k
    query, frequency = tokenizedInput[offset:offset + 2]

    for w in range(N):
        value = collection[array[w]]

        if query == 0:
            if value >= frequency:
                print array[w]
                break
        else:
            if value == frequency:
                print array[w]
                break

    else:  # aka "no break"
        print 0

大多数人会使用单独的读取语句来输入各种标量和数组值来处理这个问题。您在一开始就选择了一次阅读,这很好,但您必须在设计中注意最初的选择不会在以后妨碍您。

【讨论】:

  • 最后一个 else 的一部分是什么?没有与之相关的 if 语句。
  • 另外,我尝试运行此代码,但对于较大的输入,时间似乎没有改善
  • @krishna,elsefor 上——这是一个 Python 的东西。如评论中所述,仅当循环未通过其break 语句之一退出时才执行。仅适用于其中包含 break 语句的循环。
猜你喜欢
  • 2012-12-21
  • 2019-09-07
  • 2021-05-22
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
相关资源
最近更新 更多