青训营豆包 | 豆包MarsCode AI 刷题

55 阅读3分钟

小M的多任务下载器挑战

题目分析

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

算法步骤

  1. 事件提取

    • 对于每个任务,提取其开始时间和结束时间,并分别标记为“开始事件”和“结束事件”。
    • 将所有事件存储在一个数组中。
  2. 事件排序

    • 对事件数组进行排序,首先按时间排序,如果时间相同,则结束事件优先于开始事件。
  3. 扫描事件

    • 遍历排序后的事件数组,使用一个变量记录当前并发任务数。
    • 遇到开始事件时,增加并发任务数;遇到结束事件时,减少并发任务数。
    • 在遍历过程中,记录并发任务数的最大值。
  4. 事件提取

    • 对于每个任务,提取其开始时间和结束时间,并分别标记为“开始事件”和“结束事件”。
    • 将所有事件存储在一个数组中。
  5. 事件排序

    • 对事件数组进行排序,首先按时间排序,如果时间相同,则结束事件优先于开始事件。
  6. 扫描事件

    • 遍历排序后的事件数组,使用一个变量记录当前并发任务数。
    • 遇到开始事件时,增加并发任务数;遇到结束事件时,减少并发任务数。
    • 在遍历过程中,记录并发任务数的最大值。
代码+分析
事件数组的构造:

78c83e4b95e92f50c7d6a06fe7bcc4b.png 事件数组用于记录任务的开始和结束时间。每个任务会生成两个事件:

  • 一个是开始时间事件,表示任务开始。
  • 一个是结束时间事件,表示任务结束。

任务的结束时间是通过 start + duration 来计算的。

排序事件

1c4463b40791141a285ae91673243f7.png

为了方便计算并发数,我们需要对事件进行排序。排序的规则是:

  • 按照时间升序排序。
  • 如果时间相同,则结束事件(标记为 -1)应该排在开始事件(标记为 1)之前。这样可以避免同一时刻多个任务开始和结束时并发数的计算问题。
计算最大并发数

05816a71e323851c6a563a1c41123eb.png

  • 我们通过遍历排序后的事件数组,维护一个当前并发数(currentConcurrent),每遇到一个开始事件,当前并发数增加;遇到一个结束事件,当前并发数减少。
  • 在每次更新当前并发数时,记录最大并发数。

复杂度分析:

  • 时间复杂度:排序事件数组的时间复杂度为 O(n log n),其中 n 是任务的数量。遍历事件数组的时间复杂度为 O(n)。因此,总的时间复杂度为 O(n log n)
  • 空间复杂度:需要额外的 O(n) 空间来存储事件数组。