小M的多任务·下载器挑战||青训营笔记创作活动

55 阅读3分钟

问题描述

小M的程序设计大作业是编写一个多任务下载器。在实现过程中,他遇到了一个问题:在一次下载过程中,总共有N个任务,每个任务会在第x秒开始,并持续y秒。小M需要知道,在同一时刻,最多有多少个任务正在同时下载,也就是计算出任务的最高并发数。

  • n 表示任务的数量。
  • array 是一个二维列表,每个元素为[x, y],表示任务的开始时间和持续时间,其中:
  • x 表示任务的开始时间;
  • y 表示任务的持续时间。

测试样例

样例1:

输入:n = 2 ,array = [[1, 2], [2, 3]]
输出:2

样例2:

输入:n = 4 ,array = [[1, 2], [2, 3], [3, 5], [4, 3]]
输出:3

样例3:

输入:n = 5 ,array = [[1, 3], [3, 4], [2, 2], [6, 5], [5, 3]]
输出:3

要解决这个问题,我们需要跟踪每个任务在何时开始和何时结束,并在每个时间点计算正在进行的任务数量。具体来说,我们可以将每个任务的开始时间和结束时间看作是一个事件,并将这些事件按时间顺序排列。然后,我们遍历这些事件,每当遇到一个任务的开始时间时,就将并发任务数加一,每当遇到一个任务的结束时间时,就将并发任务数减一。在遍历过程中,我们记录并发任务数的最大值。

问题理解

你需要计算在同一时刻最多有多少个任务正在同时下载。每个任务有一个开始时间和持续时间,这意味着每个任务有一个开始时刻和一个结束时刻。

数据结构选择

为了有效地计算并发任务数,我们可以使用事件驱动的思路。具体来说,我们可以将每个任务的开始和结束视为一个事件,并记录这些事件的时间点。

def solution(n, array):
    # 创建一个列表来存储所有事件,每个事件包括时间和类型(开始或结束)
    events = []
    
    # 遍历所有任务,将开始时间和结束时间添加到事件列表中
    for x, y in array:
        events.append((x, 'start'))  # 开始时间
        events.append((x + y, 'end'))  # 结束时间
    
    # 按时间排序事件列表
    events.sort()
    
    # 初始化并发任务数和最大并发任务数
    concurrent_downloads = 0
    max_concurrent = 0
    
    # 遍历事件列表,更新并发任务数
    for time, event_type in events:
        if event_type == 'start':
            concurrent_downloads += 1
        else:
            concurrent_downloads -= 1
        
        # 更新最大并发任务数
        max_concurrent = max(max_concurrent, concurrent_downloads)
    
    return max_concurrent

# 测试样例
print(solution(2, [[1, 2], [2, 3]]))  # 输出: 2
print(solution(4, [[1, 2], [2, 3], [3, 5], [4, 3]]))  # 输出: 3
print(solution(5, [[1, 3], [3, 4], [2, 2], [6, 5], [5, 3]]))  # 输出: 3

算法步骤

  1. 事件记录

    • 对于每个任务,记录两个事件:一个开始事件和一个结束事件。
    • 开始事件的时间点是任务的开始时间。
    • 结束事件的时间点是任务的开始时间加上持续时间。
  2. 事件排序

    • 将所有事件按时间点进行排序。如果两个事件的时间点相同,优先处理结束事件(这样可以确保在同一时间点上,先减少并发数再增加)。
  3. 计算并发数

    • 遍历排序后的事件列表,使用一个计数器来记录当前的并发任务数。
    • 遇到开始事件时,增加计数器。
    • 遇到结束事件时,减少计数器。
    • 在遍历过程中,记录计数器的最大值,这个最大值就是最高并发数。