多任务下载器 | 豆包MarsCode AI刷题

97 阅读4分钟

题目: 小M的程序设计大作业是编写一个多任务下载器。在实现过程中,他遇到了一个问题:在一次下载过程中,总共有N个任务,每个任务会在第x秒开始,并持续y秒。小M需要知道,在同一时刻,最多有多少个任务正在同时下载,也就是计算出任务的最高并发数。 ·n 表示任务的数量。 array 是一个二维列表,每个元素为[x,y],表示任务的开始时间和持续时间,其中: ·x表示任务的开始时间; y 表示任务的持续时间。 要解决这个问题,我们需要计算在任意时刻,最多有多少个任务正在同时下载。具体来说,每个任务有开始时间 x 和持续时间 y,任务在时间区间 [x, x + y) 内会持续下载。我们的目标是找出最大同时下载任务数。

思路

我们可以将任务的“开始”事件和“结束”事件分别处理,使用一种事件驱动的方式来模拟任务的并发数。

  1. 事件类型

    • 对于每个任务 [x, y],我们可以将其分为两个事件:
      • 开始事件,表示任务在时间 x 开始。
      • 结束事件,表示任务在时间 x + y 结束。
  2. 处理事件

    • 将所有任务的开始时间和结束时间作为事件记录下来。
    • 对事件按时间排序。如果时间相同,结束事件优先于开始事件(防止某个任务刚好在另一个任务结束时开始,导致重复计数)。
  3. 模拟并发数

    • 遍历这些排序后的事件,维护当前并发数,并记录最大并发数。

具体步骤

  1. 创建事件列表: 对于每个任务 [x, y],生成两个事件:一个是 (x, +1)(表示开始任务),一个是 (x + y, -1)(表示结束任务)。

  2. 排序事件: 先按时间排序;如果时间相同,则结束事件 (-1) 排在开始事件 (+1) 前面。

  3. 遍历事件: 遍历排序后的事件,更新当前并发数,并记录最大并发数。

代码实现

def solution(n, array):
    events = []
    
    # 构造所有的事件
    for task in array:
        start, duration = task
        events.append((start, 1))         # 任务开始,+1
        events.append((start + duration, -1))  # 任务结束,-1
    
    # 按时间排序,时间相同则结束事件排在开始事件前
    events.sort(key=lambda x: (x[0], x[1]))
    
    max_concurrent = 0
    current_concurrent = 0
    
    # 遍历事件,更新并发数
    for event in events:
        current_concurrent += event[1]  # 事件 +1 或 -1
        max_concurrent = max(max_concurrent, current_concurrent)
    
    return max_concurrent

# 测试用例
if __name__ == "__main__":
    print(solution(2, [[1, 2], [2, 3]]) == 2)  # 两个任务完全重叠
    print(solution(4, [[1, 2], [2, 3], [3, 5], [4, 3]]) == 3)  # 在时间 2 和 3 时,有 3 个任务同时下载

解释

  1. 事件列表的构建
    • 每个任务 [x, y] 被拆成两个事件:(x, +1) 表示开始下载,(x + y, -1) 表示结束下载。
  2. 事件排序
    • 事件按时间排序,如果时间相同,结束事件 (-1) 会排在开始事件 (+1) 前面,确保我们不会重复计数任务。
  3. 遍历事件
    • current_concurrent 记录当前时刻的并发任务数,每遇到一个 +1 事件就增加并发数,每遇到一个 -1 事件就减少并发数。
    • max_concurrent 记录并发数的最大值。

复杂度分析

  • 时间复杂度:排序事件的时间复杂度是 O(n log n),其中 n 是任务数量。遍历事件的时间复杂度是 O(n)。因此,总的时间复杂度为 O(n log n)
  • 空间复杂度:我们使用了一个事件列表来存储所有任务的开始和结束事件,空间复杂度是 O(n)

测试

  1. 测试1solution(2, [[1, 2], [2, 3]]) == 2

    • 在时间 [1, 2)[2, 5) 这两个时间段内都有任务下载,最大并发数为 2。
  2. 测试2solution(4, [[1, 2], [2, 3], [3, 5], [4, 3]]) == 3

    • 在时间 [2, 3)[3, 5) 时,共有 3 个任务同时下载。

通过这种方法,我们能够高效地计算出最大并发数。

以上为本题的解题思路。