差分数组
基于labuladong的算法网站,小而美的算法技巧:差分数组
1、概述
差分数组:使用与频繁的对原始数组的某个区间的元素进行增减;
例如:
- 输入一个数组nums;
- 要求给区间nums[…]全部加x,再给区间nums[…]全部减x,再…;
- 求最后nums数组的值是什么;
这个可以用差分数组技巧,先对nums数组构造一个diff差分数组,diff[i]就是nums[i]和nums[i-1]之差:
通过差分数组可以倒推出原始数组;通过差分数组可以快速对区间增减的操作,假如想对区间nums[i,j]的元素全部加3,只需要对diff[i]+=3,diff[j+1]-=3即可:
最后的代码实现如下:
// 差分数组实现类
class Difference {
// 差分数组
int[] diff;
// 输入一个数组进行差分数组初始化
public Difference(int[] nums) {
diff = new int[nums.length];
diff[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
diff[1] = nums[i] - nums[i - 1];
}
}
// 在nums[left,right]区间里将所有元素增加val值(val可正可负)
void increment(int left, int right, int val) {
diff[left] += val;
if (right < diff.length - 1) {
diff[right + 1] -= val;
}
}
// 通过差分数组diff推出原始数组nums
int[] result() {
int[] result = new int[diff.length];
result[0] = diff[0];
for (int i = 1; i < result.length; i++) {
result[i] = result[i - 1] + diff[i];
}
return result;
}
}
2、算法实践
(1)航班预定统计
力扣第1109题,航班预定统计
[1109]航班预订统计
class Solution {
public int[] corpFlightBookings(int[][] bookings, int n) {
// 采用差分数组
int[] diff = new int[n];
int[] result = new int[n];// 最后的返回结果
for (int i = 0; i < bookings.length; i++) {
int start = bookings[i][0];
int end = bookings[i][1];
int seat = bookings[i][2];
diff[start - 1] += seat;
if (end < n) {
diff[end] -= seat;
}
}
// 将差分数组还原成原始数组
result[0] = diff[0];
for (int i = 1; i < n; i++) {
result[i] = diff[i] + result[i - 1];
}
return result;
}
}
(2)拼车
力扣第1094题,拼车
[1094]拼车
class Solution {
public boolean carPooling(int[][] trips, int capacity) {
int[] diff = new int[1001];// 根据提示得到的信息
// 遍历数组生成差分数组
for (int i = 0; i < trips.length; i++) {
int passengers = trips[i][0];
int from = trips[i][1];
int to = trips[i][2];
// 给[from,to]区间的元素加passengers
increment(diff, from, to, passengers);
}
int[] result = getOrigin(diff);
for (int i = 0; i < result.length; i++) {
if (result[i] > capacity) {
return false;
}
}
return true;
}
// 将差分数组 diff[left,right]中的全部元素加value
void increment(int[] diff, int left, int right, int value) {
diff[left] += value;
diff[right] -= value;
}
// 将差分数组变成原始数组
int[] getOrigin(int[] diff) {
int[] result = new int[diff.length];
result[0] = diff[0];
for (int i = 1; i < diff.length; i++) {
result[i] = diff[i] + result[i - 1];
}
return result;
}
}