差分数组的定义
差分数组就是原始数组相邻元素的差。
定义如下,给定原始数组nums,则对应的差分数组min就是相邻元素之间的差,用公式表示为:
数组定义的性质:
- 原数组nums中的每一项num[i] 是差分数组min[i]的前缀和,用公式表示为
差分数组可以维护多次对数组的一个区间加上一个数,并在最后询问某一位的数值或者多次询问某一位的数值。
举例:
序号 | 0 | 1 | 2 | 3 | 4 |
原数组nums | 2 | 4 | 9 | 7 | 10 |
差分数组min | 2 | 2 | 5 | -2 | 3 |
其实差分数组是一个辅助数组,从侧面来表示给定某一数组的变化,一般用来对数组进行区间修改的操作。
比如上面的数组,我们需要进行以下操作:
- 将区间[0,2]之间的数值加3
- 将区间[1,3]之间的数值减5
第一个操作
序号 | 0 | 1 | 2 | 3 | 4 |
原数组nums | 2+3=5 | 4+3=7 | 9+3=12 | 7 | 10 |
差分数组min | 2+3=5 | 2不变 | 5不变 | -2-3=-5 | 3 |
第二个操作
序号 | 0 | 1 | 2 | 3 | 4 |
原数组nums | 2+3=5 | 4+3=7-5=2 | 9+3=12-5=7 | 7-5=2 | 10 |
差分数组min | 2+3=5 | 2-5=-3 | 5不变 | -2-3=-5不变 | 3+5=8 |
这时我们就会发现这样一个规律,当对一个区间进行增减某个值的时候,他的差分数组对应的区间左端点的值会同步变化,而他的右端点的后一个值则会相反地变化。
差分数组的应用
差分数组的作用就是求多次进行区间修改后的数组。
注意:只能是区间元素同时增加或减少相同的数的情况才能用
因为我们的差分数组是由原始数组的相邻两项作差求出来的,即 nums[i]=nums[i]-nums[i-1];那么我们能不能反过来,求得一下修改过后的nums[i]呢?
直接反过来即得 nums[i]=nums[i-1]+min[i]
差分数组在力扣题目中的使用
/**
* @param {number[][]} bookings
* @param {number} n
* @return {number[]}
*/
var corpFlightBookings = function(bookings, n) {
//航班预订初始值为0,对应的差分数组值也为0
const nums = new Array(n).fill(0);
for(const book of bookings){
//差分数组左断点操作值
nums[book[0]-1] += book[2];
if(book[1] < n){
//差分数组右端点反向操作
nums[book[1]] -= book[2];
}
}
for(let i=1;i<n;i++){
//求前缀和
nums[i] = nums[i] + nums[i-1];
}
return nums;
};
/**
* @param {number[][]} trips
* @param {number} capacity
* @return {boolean}
*/
var carPooling = function(trips, capacity) {
const nums = new Array(1002).fill(0);
let sum = 0;
for(const trip of trips){
nums[trip[1]] += trip[0];
if(trip[2] < 1000){
nums[trip[2]] -= trip[0];
}
}
for(let i=0;i<nums.length;i++){
sum += nums[i];
if(sum > capacity){
return false;
}
}
return true;
};