差分法
我们先要了解何为差分数组,以及它可以解决什么问题。
利用差分数组可以做到对原数组的某一个区间 [l,r] 施加一个增量inc,并且这种增加可以叠加。
比直接暴力求解该类问题速度要更快。
差分数组对应的概念是前缀和数组,对于数组 [1,2,2,4],其差分数组为 [1,1,0,2]。
差分数组的每一个数代表后一个数比前一个数大了多少,差分数组的第 i个数即为原数组的第 i−1 个元素和第 i 个元素的差值,也就是说我们对差分数组求前缀和即可得到原数组。
差分数组的性质是,当我们希望对原数组的某一个区间 [l,r] 施加一个增量inc 时,差分数组 d 对应的改变是d[l] 增加 inc,d[r+1]] 减少 inc。也就是只用给d[i]添加即可,因为该区间内整体增加,因此该区间内数的大小差异不变,那么这样还原会原数组时就是实现了该区域内的整体累加。而最后在d[r+1]处减少inc,因为前面的数整体增加,在差分数组内就相当于给该区间后面第一个数减少了inc,就可以不让该区内的累加影响到原数组中后面的数.
这样对于区间的修改就变为了对于两个位置的修改。并且这种修改是可以叠加的,即当我们多次对原数组的不同区间施加不同的增量,我们只要按规则修改差分数组即可。
例如该题:
力扣第1109题——航班预定统计
该题想要根据已给的数组让我们求出每个航班上的预定座位数,其本质就是让我们根据已给出的二元数组,该数组存储着某一个航班区间内的座位数,我们根据该数组对结果数组不断进行累加求出结果数组。
题解为
class Solution {
public int[] corpFlightBookings(int[][] bookings, int n) {
//定义结果数组
int[] nums = new int[n];
//根据二维数组构建差分数组
for (int[] booking : bookings) {
nums[booking[0] - 1] += booking[2];
if (booking[1] < n) {
nums[booking[1]] -= booking[2];
}
}
//根据差分数组得到目标数组
for (int i = 1; i < n; i++) {
nums[i] += nums[i - 1];
}
return nums;
}
}