小M的多任务下载器挑战 | 豆包MarsCode AI刷题

161 阅读3分钟

问题描述

小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_countmax_count)来跟踪当前和最大并发数,这些变量的空间复杂度是常数级别的,即O(1)。
综上所述,整个算法的空间复杂度主要由事件列表决定,为O(N)。