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

246 阅读3分钟

问题解析

我们需要计算在同一时刻最多有多少个任务正在下载。每个任务有其开始时间和持续时间,这样就能确定其结束时间。为了解决这个问题,我们可以通过事件(任务开始和任务结束)在时间轴上进行处理,并实时计算同时进行的任务数。

解题思路

  1. 事件记录:每个任务有开始时间和结束时间。对于每个任务,我们可以记录两类事件:

    • 开始事件:当任务开始时,表示一个任务增加。
    • 结束事件:当任务结束时,表示一个任务减少。
  2. 时间轴排序:将所有的开始和结束事件记录到一个时间轴列表中。然后按时间排序:

    • 如果有多个事件发生在同一时刻,结束事件应排在开始事件之前,以确保任务结束和新任务开始发生时并发数的计算准确。
  3. 遍历时间轴:初始化一个计数器 current_concurrency 来记录当前正在下载的任务数,以及一个变量 max_concurrency 来记录遇到的最大并发数。

    • 遍历时间轴,每遇到一个开始事件,计数器加1;每遇到一个结束事件,计数器减1。
    • 在每个事件处理完后,更新 max_concurrencycurrent_concurrency 的最大值。

代码实现

以下是代码实现,详细注释解释了每个步骤:


def solution(n, array):
    # 创建一个列表来记录所有的时间事件
    timeline = []
    
    # 遍历每个任务,记录开始和结束时间的事件
    for task in array:
        start_time = task[0]                 # 任务开始时间
        end_time = task[0] + task[1]         # 任务结束时间(开始时间 + 持续时间)
        timeline.append((start_time, 1))     # 1表示任务开始
        timeline.append((end_time, -1))      # -1表示任务结束
    
    # 对时间事件进行排序,先按时间排序;若时间相同,结束事件优先
    timeline.sort(key=lambda x: (x[0], x[1]))

    # 初始化计数器和最大并发数
    current_concurrency = 0
    max_concurrency = 0
    
    # 遍历时间轴,计算最大并发数
    for time, event in timeline:
        current_concurrency += event               # 更新当前并发数
        max_concurrency = max(max_concurrency, current_concurrency)  # 更新最大并发数
    
    return max_concurrency

示例测试

以下是对几个测试样例的调用和结果验证:

if __name__ == "__main__":
    # 添加测试用例
    print(solution(2, [[1, 2], [2, 3]]) == 2)      # 输出: 2
    print(solution(4, [[1, 2], [2, 3], [3, 5], [4, 3]]) == 3)  # 输出: 3
    print(solution(5, [[1, 3], [3, 4], [2, 2], [6, 5], [5, 3]]) == 3)  # 输出: 3

示例分析

  • 样例1:

    • 任务1从第1秒开始,持续2秒,即在 [1, 3) 内下载。
    • 任务2从第2秒开始,持续3秒,即在 [2, 5) 内下载。
    • 从第2秒到第3秒同时有两个任务在下载,因此并发数为2。
  • 样例2:

    • 时间段 [3, 5) 内,有三个任务在下载,所以最大并发数为3。
  • 样例3:

    • 时间段 [3, 6) 内,最多有3个任务在下载,因此最大并发数为3。

复杂度分析

  • 时间复杂度:对于每个任务,我们生成两个事件,所以时间复杂度为 O(n)。排序时间复杂度为 O(n log n)
  • 空间复杂度:用于存储事件列表的空间复杂度为 O(n)