题目描述
小M的程序设计大作业是编写一个多任务下载器。在实现过程中,他遇到了一个问题:在一次下载过程中,总共有N个任务,每个任务会在第x秒开始,并持续y秒。小M需要知道,在同一时刻,最多有多少个任务正在同时下载,也就是计算出任务的最高并发数。
n表示任务的数量。array是一个二维列表,每个元素为[x, y],表示任务的开始时间和持续时间,其中:x表示任务的开始时间;y表示任务的持续时间。
最朴素的思路是构建一个时间列表,按时间顺序记录每个时刻正在执行的任务数量。具体操作时,针对每个任务,依据其开始时间和持续时间,在对应的时间区间内,对列表里涉及的每个时刻元素加 1,以此体现任务执行情况。全部任务更新完毕后,遍历该时间列表,找出其中数值最大的元素,此数值即为任务最高并发数。
不过,这种方法存在明显缺陷。在更新时间列表时,因要精准定位每个任务对应的时间区间,再逐个对区间内的元素做加 1 操作,过程十分繁琐。一旦任务量增多、时间跨度复杂,操作量会剧增,效率会变得非常低。而差分数组就是和这种区间更新操作。接下来,简要介绍下差分数组。
差分数组
差分数组是一种常见的算法工具,用于快速实现区间更新操作。它利用累积的差分值记录对区间的影响,从而将原本需要逐个修改元素的操作优化为对两个位置的赋值操作。
差分数组的核心思想
差分数组是一种将区间操作转化为点操作的方法:
差分数组记录的是相邻元素的差值,而不是原数组的值。
如果我们要对某个区间
[l, r]执行统一加/减操作,可以通过修改差分数组的两个位置来实现。
公式
给定一个数组 nums 和对应的差分数组 delta,有以下关系:
构造差分数组:
delta[i]=nums[i]−nums[i−1](i≥1)
由差分数组还原原数组:
nums[i]=nums[i−1]+delta[i]
对区间 [l, r] 加上一个值 x
delta[l]+=x
delta[r+1]−=x
实现
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;
}