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