给出人员日程表的会议开始时间和结束时间的列表,找到给定时间的人数。时间将以整数形式给出。例如:
输入为
[ [ 12, 14] ,[12,15],[14,16],[13,15]]
输出应返回
[ 0,0,0,0,0,0,0,0,0,0,0,2,3,4,3,1]
如何在线性时间内完成?
我可以在O(n*m)
中做到这一点。
要查找每个输出,请扫描输入并查找给定时间内的总人数。这需要O(n*m)
n =输入的大小,m =输出的大小
答案 0 :(得分:1)
在O(n + m)时间内完成此操作的技巧是:
out
数组并用零(O(m)时间)填充它[a,b]
,out[a]+=1; out[b+1]-=1
(O(n)次)for (int i=1; i<out.length; ++i) out[i]+=out[i-1];
答案 1 :(得分:0)
显而易见的算法效果很好:
def schedule(spans):
s = [0] * max(map(max, spans))
for lo, hi in spans:
for t in range(lo - 1, hi):
s[t] += 1
return s
print str(schedule([[12, 14],[12,15],[14,16],[13,15]]))
这是O(L + n),其中L是所有跨度的总长度,n是输出的大小。
然后:
$ python foo.py
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 3, 1]
现在,如果您有许多重叠的间隔,则可以使用一维扫掠线算法来计算O(n log n + m)时间的结果,其中n是数字间隔,m是输出时间单位的数量。
类似这样的东西,尽管我一点也不声称这是完全正确的:
def schedule_faster(spans):
events = []
for lo, hi in spans:
events.append((lo, '+'))
events.append((hi + 1, '-'))
events.sort()
s = [0] * max(map(max, spans))
n = 0
t_last = events[0][0]
for t, dir in events:
if t != t_last:
for i in range(t_last - 1, t - 1):
s[i] = n
t_last = t
n += 1 if dir == '+' else -1
return s
实际上,如果您使用基数排序或其他伪线性时间排序算法,则实际上它变为O(n + m)。