嘿,我正在尝试解决这个python练习问题,但是我的解决方案不在给定的时间限制内,有人可以解释一下。这将对您非常有帮助,因为在任何地方我都找不到这个问题的python解决方案,他们在Java中给出了与我几乎相同的解决方案
tasks_count = int(input())
tasks = []
def binarysearch(x):
arr = tasks
if arr == [] or x > arr[0]: return 0
elif x < arr[-1]: return len(arr)
l = 0
r = len(arr)
while l <= r:
mid = int((l + r) / 2);
if arr[mid] == x:
return mid
elif arr[mid] > x:
l = mid - 1
else:
r = mid + 1
return mid
for i in range(0, tasks_count):
n = input().split(' ')
if n[0] == '1':
pos = binarysearch(int(n[1]))
tasks.insert(pos, int(n[1]))
elif len(tasks) < 3:
print('Not enough enemies')
else:
print(tasks[(int(len(tasks)/3))])
解决方案2:
tasks_count = int(input())
tasks = []
for i in range(0, tasks_count):
n = input().split(' ')
if n[0] == '1':
tasks.append(int(n[1]))
elif len(tasks) < 3:
print('Not enough enemies')
else:
tasks.sort(reverse=True)
print(tasks[int(len(tasks)/3)-1])
答案 0 :(得分:0)
解决方案#2主要是目标,但是有一些问题会不必要地减慢它的速度。一方面,input
函数比直接从sys.stdin
读取要慢得多;根据我的简短实验,循环range
和调用input
的时间比循环islice
的{{1}}的时间长10倍。
它还会执行一些复杂的计算,将索引转换为sys.stdin
再返回到float
,这可以避免:
int
可以直接计算为:
int(len(tasks)/3)-1
使用len(tasks) // 3 - 1
下位除法运算符直接计算//
。
一个较小的改进是用int
分隔行,这样您就不必处理手动索引编制了(这可能会很慢,而且读起来不那么明显)。
最后的优化是将您的工作捆绑在一个函数调用中; CPython变量在全局范围内存储和加载需要str.partition
操作,而在局部范围内,它们是运行速度更快的简单C数组查找。
在所有这些因素中,您最终得到的代码更像:
dict
如果他们有意强制执行频繁的排序,这可能仍然太慢(因为Python的TimSort尝试有效地处理大多数排序的输入,相对于简单的索引和附加,它仍然需要大量工作)。可能需要使用import sys
from itertools import islice
def main():
tasks_count = int(next(sys.stdin))
tasks = []
for line in islice(sys.stdin, tasks_count):
task_type, sep, task_value = line.partition(' ')
if task_type == '1':
tasks.append(int(task_value))
elif len(tasks) < 3:
print('Not enough enemies')
else:
tasks.sort(reverse=True)
print(tasks[len(tasks) // 3 - 1])
if __name__ == '__main__': # Standard import guard
main() # Call main
模块(该模块为您实现二进制搜索,但在运行速度更快的扩展模块中)保持排序不变,在这种情况下,您删除了{{1} }进行完全调用,以使其在插入时保持有序(将每个任务#2的bisect
工作替换为每个任务#1的sort
工作)。方便地,由于Python允许使用负索引,因此您不必按降序对其进行排序,因此同样可以轻松地(如果不太容易)沿向上方向计算所需索引:
O(n log n)