题目描述
思路解析动画文字版
两步走:先把每条预订记成「左端 +seats、右端下一格 −seats」两个标记;最后做一次前缀和,把标记摊开成答案。下面一步步演。
先准备一个长度为 5 的差分数组 diff,每一格都是 0。它不直接存座位,而是存「在这里座位发生了多少变化」。
第 1 条预订:第 1 班到第 2 班,每班加 10 个座位。高亮区间就是要被加座的航班。
左端标记:在区间起点下标 0 处加上 10。这代表「从这一班开始,每班多 10 个座位」。
右端收尾:在区间右端的下一格下标 2 处减去 10。这代表「从这一班起,前面多加的 10 个座位不再算」,正好把加座限制在区间内。
第 2 条预订:第 2 班到第 3 班,每班加 20 个座位。高亮区间就是要被加座的航班。
左端标记:在区间起点下标 1 处加上 20。这代表「从这一班开始,每班多 20 个座位」。
右端收尾:在区间右端的下一格下标 3 处减去 20。这代表「从这一班起,前面多加的 20 个座位不再算」,正好把加座限制在区间内。
第 3 条预订:第 2 班到第 5 班,每班加 25 个座位。高亮区间就是要被加座的航班。
左端标记:在区间起点下标 1 处加上 25。这代表「从这一班开始,每班多 25 个座位」。
这条预订的右端是最后一班,再往后没有航班了,所以不需要记 −25:加座自然延续到结尾。
三条预订都记完了,差分数组 diff = [10, 45, -10, -20, 0]。注意全程只改了几个位置,没有逐格循环。下面做前缀和把它摊开。
前缀和登场:准备一个累加器 run=0,指针从最左格出发,依次把每格的增减量加进 run,得到的就是真实座位数。
指针走到下标 0。这一格记的增减量是 10,马上把它累加进 run。左边绿色是已经还原好的航班。
累加完成:run 变成 10,这就是第 1 班的真实座位数,写回下标 0。绿色又多了一格。
指针走到下标 1。这一格记的增减量是 45,马上把它累加进 run。左边绿色是已经还原好的航班。
累加完成:run 变成 55,这就是第 2 班的真实座位数,写回下标 1。绿色又多了一格。
指针走到下标 2。这一格记的增减量是 -10,马上把它累加进 run。左边绿色是已经还原好的航班。
累加完成:run 变成 45,这就是第 3 班的真实座位数,写回下标 2。绿色又多了一格。
指针走到下标 3。这一格记的增减量是 -20,马上把它累加进 run。左边绿色是已经还原好的航班。
累加完成:run 变成 25,这就是第 4 班的真实座位数,写回下标 3。绿色又多了一格。
指针走到下标 4。这一格记的增减量是 0,马上把它累加进 run。左边绿色是已经还原好的航班。
累加完成:run 变成 25,这就是第 5 班的真实座位数,写回下标 4。绿色又多了一格。
扫到末尾,差分数组被前缀和摊开成最终答案 [10, 55, 45, 25, 25],就是每个航班被订的总座位数。
三个高频追问:差分为何快、前缀和在干嘛、两者互逆。
参考代码
def corpFlightBookings(bookings, n): diff = [0] * (n + 1) # 多留一格放右端 -seats for first, last, seats in bookings: diff[first - 1] += seats # 左端 +seats diff[last] -= seats # 右端下一格 -seats ans = [0] * n run = 0 for i in range(n): run += diff[i] # 前缀和还原 ans[i] = run return ans复杂度
- 时间:O(n + m),m 条预订各打两个标记,再 O(n) 前缀和扫一遍;与区间长度无关
- 空间:O(n),只额外用一个长度 n+1 的差分数组
易错点
面试追问把动画讲成自己的话
追问差分数组为什么能把「整段加」变快?
追问前缀和那一步在做什么?
追问差分和前缀和是什么关系?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
将矩阵按对角线排序
LeetCode 1329 · 中等 · 沿着 数组套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题