小而美的算法技巧:差分数组
差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。
差分数组每一个元素 df[i]
储存数组元素与上一个元素的差值 nums[i] - nums[i-1]
。
差分数组可以直接还原为原数组,只需遍历一遍差分数组,加上上一个元素即可。
| for i := 1; i < n; i++ { df[i] = df[i-1] + df[i] }
|
航班预订统计
https://leetcode-cn.com/problems/corporate-flight-bookings/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| func corpFlightBookings(bookings [][]int, n int) []int { df := make([]int, n) for _, booking := range bookings { df[booking[0]-1] += booking[2] if booking[1] < n { df[booking[1]] -= booking[2] } } for i := 1; i < n; i++ { df[i] = df[i-1] + df[i] } return df }
|
拼车
https://leetcode-cn.com/problems/car-pooling/
和上一题基本一样,有几点注意的:
- 题目限定了路程长度最多为 1000,所以差分数组也初始化为 1000
- 乘客会先下后上,所有到达终点时车的容量就会马上增加,因此在终点区间就可以减去人数
- 注意起点 0 时可能上了多个乘客但是没判断到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| func carPooling(trips [][]int, capacity int) bool { n := 1000 df := make([]int, n) for _, trip := range trips { df[trip[1]] += trip[0] if trip[2] < n { df[trip[2]] -= trip[0] } } if df[0] > capacity { return false } for i := 1; i < n; i++ { df[i] = df[i-1] + df[i] if df[i] > capacity { return false } } return true }
|