问题描述
小M的程序设计大作业是编写一个多任务下载器。在实现过程中,他遇到了一个问题:在一次下载过程中,总共有N个任务,每个任务会在第x秒开始,并持续y秒。小M需要知道,在同一时刻,最多有多少个任务正在同时下载,也就是计算出任务的最高并发数。 n 表示任务的数量。 array 是一个二维列表,每个元素为[x, y],表示任务的开始时间和持续时间,其中: x 表示任务的开始时间; y 表示任务的持续时间。
程序分析
题目要求计算在一次下载过程中,最多有多少个任务同时进行。我们有N个任务,每个任务有一个开始时间和持续时间。我们需要找到任务的最高并发数,即在同一时刻最多有多少个任务正在同时下载。
对于每个任务,我们定义两个事件:开始事件和结束事件。开始事件表示任务开始下载的时间点,结束事件表示任务完成下载的时间点。我们将所有任务的开始和结束事件放入一个列表中。每个事件是一个元组,包含时间点和事件类型(1表示开始,-1表示结束)。
我们将事件列表按照时间点进行排序。如果两个事件的时间点相同,结束事件(-1)应该排在开始事件(1)之前,以确保我们正确地计算并发数。
遍历排序后的事件列表,并使用一个变量来跟踪当前的并发任务数量。每当我们遇到一个开始事件,将并发数增加1;每当我们遇到一个结束事件,我们将并发数减少1。同时,我们使用另一个变量来跟踪记录并发数的最大值。在遍历完所有事件后,我们找到的最大并发数就是我们需要的结果。
测试样例
输入:n = 2 ,array = [[1, 2], [2, 3]]
输出:2
输入:n = 4 ,array = [[1, 2], [2, 3], [3, 5], [4, 3]]
输出:3
输入:n = 5 ,array = [[1, 3], [3, 4], [2, 2], [6, 5], [5, 3]]
输出:3
代码实现
def solution(n, array):
events = []
for a in array:
start = a[0]
cte = a[1]
end = start + cte
events.append((start, 1))
events.append((end, -1))
# 排序时,时间点相同的情况下,结束事件优先
events.sort(key=lambda x: (x[0], x[1]))
max_count = 0
current_count = 0
for e in events:
current_count += e[1]
if current_count > max_count:
max_count = current_count
#实时更新最大并行数
return max_count
if __name__ == "__main__":
# Add your test cases here
print(
solution(2, [[1,2], [2,3]]) == 2
)
print(
solution(4, [[1,2], [2,3],[3,5], [4,3]]) == 3
)
时间复杂度
遍历N个任务,为每个任务创建两个事件,这一步的时间复杂度是O(N)。
对2N个事件进行排序,使用高效的排序算法(如快速排序、归并排序)的时间复杂度是O(NlogN)。这是因为排序算法的时间复杂度通常以元素数量的对数为基准。
在排序后的事件列表上进行单次遍历,这一步的时间复杂度是O(N)。
综上所述,整个算法的时间复杂度主要由排序步骤决定,为O(NlogN)。
空间复杂度
我们需要存储所有任务的开始和结束事件。对于N个任务,我们将有2N个事件(每个任务一个开始事件和一个结束事件)。因此,事件列表的空间复杂度是O(N)。
在排序过程中,我们不会创建额外的数据结构,只是对事件列表进行排序,所以排序后的空间复杂度仍然是O(N)。
我们使用了几个额外的变量(如current_count和max_count)来跟踪当前和最大并发数,这些变量的空间复杂度是常数级别的,即O(1)。
综上所述,整个算法的空间复杂度主要由事件列表决定,为O(N)。