小M的多任务下载器挑战-差分数组解决

105 阅读2分钟

小M的多任务下载器挑战-差分数组解决

题目描述

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

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

最朴素的思路是构建一个时间列表,按时间顺序记录每个时刻正在执行的任务数量。具体操作时,针对每个任务,依据其开始时间和持续时间,在对应的时间区间内,对列表里涉及的每个时刻元素加 1,以此体现任务执行情况。全部任务更新完毕后,遍历该时间列表,找出其中数值最大的元素,此数值即为任务最高并发数。

不过,这种方法存在明显缺陷。在更新时间列表时,因要精准定位每个任务对应的时间区间,再逐个对区间内的元素做加 1 操作,过程十分繁琐。一旦任务量增多、时间跨度复杂,操作量会剧增,效率会变得非常低。而差分数组就是和这种区间更新操作。接下来,简要介绍下差分数组。

差分数组

差分数组是一种常见的算法工具,用于快速实现区间更新操作。它利用累积的差分值记录对区间的影响,从而将原本需要逐个修改元素的操作优化为对两个位置的赋值操作。


差分数组的核心思想

差分数组是一种将区间操作转化为点操作的方法:

  1. 差分数组记录的是相邻元素的差值,而不是原数组的值。
  2. 如果我们要对某个区间 [l, r] 执行统一加/减操作,可以通过修改差分数组的两个位置来实现。
公式
  • 给定一个数组 nums 和对应的差分数组 delta,有以下关系:

    • 构造差分数组

      delta[i]=nums[i]nums[i1](i1)delta[i]=nums[i]−nums[i−1](i≥1)
      delta[0]=nums[0]delta[0]=nums[0]
    • 由差分数组还原原数组

      nums[i]=nums[i1]+delta[i]nums[i]=nums[i−1]+delta[i]
  1. 对区间 [l, r] 加上一个值 x

    • delta[l]+=xdelta[l]+=x
    • delta[r+1]=xdelta[r+1]−=x

通过累积差分数组 delta,可以高效地更新数组的值,而不用逐个更新每个元素。

实现

 public static int solution(int n, int[][] array) {
     int[] diff = new int[10000];
     diff[0] = 0;
     for(int i=0;i<array.length;i++){
         diff[array[i][0]]+=1;
         diff[array[i][0] + array[i][1]]-=1;
     }
     int max = 0;
     int now = 0;
     for(int i=1;i<diff.length;i++){
         now += diff[i];
         max = Math.max(now,max);
     }
     return max;
 }