考虑一下,我有一个日志寄存器,用于记录用户从某些服务器进入和退出的时间。我需要找到最大会话数的时间。如果有多个答案,则应选择最小的答案。输入的第一行包含会话数。
示例 输入:
5
4 5
0 3
1 9
7 8
2 6
输出:
2
我尝试了以下脚本:
from collections import Counter, OrderedDict
load = Counter()
with open("input.txt", "r") as f:
n = int(f.readline())
for i in range(n):
session = f.readline()
session = session.split()
load.update(range(int(session[0]), int(session[1])+1))
load = load.most_common()
i = 0
max = load[0][1]
candidates = []
while load[i][1] == max:
candidates.append(load[i][0])
i += 1
print(min(candidates))
首先,我使用Counter()
对所有点的出现进行计数。其次,我使用load = load.most_common()
按出现的顺序来排序结果。最后,我找到所有键的最小值和相应的最大值(=出现的次数)。
实际上,如果Counter()
返回了按键排序的字典,则它将简单得多。
无论如何,这是我的主任务,并且在其中一个测试输入上运行超过1秒(给定时间限制)。可以采取什么措施来加快速度?我已经阅读了有关间隔树的信息,但不确定是否相关。
答案 0 :(得分:1)
为此的快速解决方案是在进入/退出时间存储+ 1,-1-然后对字典键进行排序并对其求和,然后求和,然后得到最大值:
data = """5
4 5
0 3
1 9
7 8
2 6"""
with open("input.txt", "w") as f:
f.write(data)
d = {}
with open("input.txt", "r") as f:
next(f)
for line in f:
if line.strip():
start, stop = map(int,line.strip().split())
d.setdefault(start,0)
d[start] += 1
d.setdefault(stop,0)
d[stop] -= 1
maxx = 0
s = 0
max_idx = 0
# iteratively summ over sorted times from dict
for idx,key in enumerate(sorted(d)):
s += d[key]
if maxx < s: # remembert new max_idx and max
maxx = s
max_idx = idx
print(max_idx)
如果defaultdict(int)仍然太慢而无法解决挑战,则可以使用。
答案 1 :(得分:1)
假设ins
和outs
是登录和注销时间:
ins = [4,0,1,7,2]
outs = [5,3,9,8,6]
在一个排序的列表中用数字的符号将其组合起来,以表明它是“到达”(正)还是“出发”(负):
times = sorted(ins + [-x for x in outs], key=abs)
现在,遍历列表并计算发生的“到达”和“离开”:
lmax = -1
logged = 0
for t in times:
if t >= 0:
logged += 1
if logged > lmax:
tmax = t
lmax = logged
else:
logged -= 1
print(tmax, lmax)
#2 3