这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战
leetcode-1109-航班预订统计
[博客链接]
[题目描述]
这里有 n 个航班,它们分别从 1 到 n 进行编号。
有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。
请你返回一个长度为 n 的数组 answer,其中 answer[i] 是航班 i 上预订的座位总数。
示例 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⁴
- 1 <= bookings.length <= 2 * 10⁴
- bookings[i].length == 3
- 1 <= firsti <= lasti <= n
- 1 <= seatsi <= 10⁴
Related Topics
- 数组
- 前缀和
- 👍 179 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:暴力扫描
- 这种方法目前是不会TLE
- 不过不知道后续会不会加数据集
- 暴力的思路很简单,就定一个数组,然后里面写for循环即可
public int[] corpFlightBookings(int[][] bookings, int n) {
int[] res = new int[n];
for (int[] booking : bookings
) {
int l = booking[0] - 1, r = booking[1] - 1;
while (l <= r) {
res[l] += booking[2];
l++;
}
}
return res;
}
- 时间复杂度O()
- 空间复杂度O(n)
思路二:差分数组+前缀和
- 这种题当然不能用这么暴力的方法来解决
- 类似这种区间求和的问题最开始想到的一定是前缀和
- 本题又有区间重叠,所以使用差分数组/线段树往往是求解方法
- 这道题只用到了差分数组
- 定义一个数组d[] d[i] = a[i]-a[i-1];
- 初始化d[i] = 0
- 每加上一个区间三元组[l,r,cnt]
- 表示 l->r 有cnt个订单
- d[l] += cnt,d[r+1]-=cnt;
- 这样就可以通过d[]使用前缀和反推最后的res数组
public int[] corpFlightBookings(int[][] bookings, int n) {
int[] d = new int[n + 1];
for (int[] booking : bookings) {
int l = booking[0] - 1, r = booking[1] - 1, cnt = booking[2];
d[l] += cnt;
d[r + 1] -= cnt;
}
for (int i = 1; i < n; i++) {
d[i] +=d[i-1];
}
return Arrays.copyOfRange(d,0,d.length-1);
}
- 时间复杂度O(n)
- 空间复杂度O(n)
最后的话
写在本月连载31天后的话,大概率以后更新也不会这么频繁了,要换新工作了,没有这么长时间的摸鱼了,不过题估计还会一直刷,对于一些有趣的问题也会更新题解,对于简单的可能就不会再更新无用题解了,算法大概是我唯一的工作乐趣了,也希望越来越多的人能够刷算法,找到解题的快感!感谢三叶大佬!我一定会和三叶一起坚持下去的!