持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
一、题目描述:
这里有 n 个航班,它们分别从 1 到 n 进行编号。
有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。
请你返回一个长度为 n 的数组 answer,里面的元素是每个航班预定的座位总数。
示例 1:
输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
输出:[10,55,45,25,25]
解释:
航班编号 1 2 3 4 5
预订记录 1 : 10 10
预订记录 2 : 20 20
预订记录 3 : 25 25 25 25
总座位数: 10 55 45 25 25
因此,answer = [10,55,45,25,25]
示例 2:
输入:bookings = [[1,2,10],[2,2,15]], n = 2
输出:[10,25]
解释:
航班编号 1 2
预订记录 1 : 10 10
预订记录 2 : 15
总座位数: 10 25
因此,answer = [10,25]
提示:
- 1 <= n <= 2 * 10^4
- 1 <= bookings.length <= 2 * 10^4
- bookings[i].length == 3
- 1 <= firsti <= lasti <= n
- 1 <= seatsi <= 10^4
二、思路分析:
适用:频繁对原始数组的某个区间的元素进行增减。
- 先对nums数组构造一个diff差分数组,diff[i] = nums[i] - nums[i - 1]。
- 再通过diff差分数组,可反推出原始数组:nums[i] = nums[i-1] + diff[i];
- 若想对区间nums[i..j]的元素全部+3,则只需让diff[i]+=3,再让diff[j+1] -=3。因为:diff[i]+=3意味着nums[i..]的所有元素都加了3;diff[j+1] -=3意味着对于nums[j+1..]的所有元素再减3,综合起来,就是对nums[i..j]中的所有元素都加了3.
- 只花费O(1)时间修改diff数组,就相当于给nums整个区间进行了修改。多次修改diff,然后通过diff反推,即可得到nums修改后的结果。
三、AC 代码:
class Solution {
public int[] corpFlightBookings(int[][] bookings, int n) {
int[] nums = new int[n]; //返回的结果集,也就是加加减减之后最终每个航班预订的座位总数
Arrays.fill(nums, 0);
Difference df = new Difference(nums); // 构造差分解法
for(int[] booking : bookings){
//获取三个参数,并传入差分函数
int i = booking[0] - 1; //区间左边界, 注意转成数组索引要减一
int j = booking[1] - 1;
int val = booking[2];
df.increment(i, j, val); // 对区间 nums[i..j] 增加 val
}
return df.result(); // 返回最终的结果数组
}
}
class Difference{
private int[] diff;
public Difference(int[] nums){
assert nums.length > 0;
//构造差分数组
diff = new int[nums.length];
diff[0] = nums[0];
for(int i = 1; i < nums.length; i++){
diff[i] = nums[i] - nums[i - 1];
}
}
//修改[i,j]区间的数值,增val(可负)
public void increment(int i, int j, int val){
diff[i] += val;
if(j + 1 < diff.length){
diff[j + 1] -= val;
}
}
//返回修改后的结果数组
public int[] result(){
int[] res = new int[diff.length];
res[0] = diff[0];
for(int i = 1; i < diff.length; i++){
res[i] = res[i - 1] + diff[i];
}
return res;
}
}