【算法通关】1109. 航班预订统计——差分数组

1,053 阅读3分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战


前天华为一面碰到这个题,还说给30分钟考虑。当时我就笑了,2分钟写了个暴力法,自信满满给面试官看。面完10分钟不到就给挂了╭( T □ T )╮

——leetcode此题热评

前言

大家好,我是一条,欢迎来到我的算法频道。

只做有趣的算法题,只为面试写算法

Question

1109. 航班预订统计

难度:中等

这里有 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]

提示:

1 <= n <= 2 * 104
1 <= bookings.length <= 2 * 104
bookings[i].length == 3
1 <= firsti <= lasti <= n
1 <= seatsi <= 104

Solution

题目看一遍好像不太懂,不慌,看示例,多看几遍,懂了。

原来就这,暴力法解决,哎,不对,超时了。

啊,这!

这属于区间求和的一到典型题——「区间修改」+「单点查询」问题。

考虑用差分数组修改,前缀和单点查询。

重点聊差分数组,简单说就是一个用来辅助的数组,计算每个相邻数组元素的差,形成一个新的数组,即d[i]=arr[i]-arr[i-1](i≠0),d[i]=0

有什么用呢?解决频繁区间修改操作,比如让第1个数到第1000万个数每个数都加上1,而且这种操作是频繁的。

因为在区间内每个数都加1,其实差是不变的,只需要将区间首的差值+1,区间尾的差值-1。修改1000万个数,只需要改差值数组的两个数。

ok,差值数组建好了,那不是占空间了吗?

没错,就是空间换时间的算法,有了差值数组,即使你频繁修改,针对任何一个单点查询,都可以通过前缀和求解。

回到本题:bookings二维数组每一行有三个数,前两个数代表航班区间左右端点,最后一个数代表数量,这个数量只对区间内的航班“有效”,所以在左端点进行+操作,在区间结束的第一个位置进行-操作然后对差分数组求前缀和即可。

Code

/**
 * @author 一条coding
 */
class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
        int[] nums = new int[n];
      // 
        for (int[] booking : bookings) {
          // 左端点进行+操作
            nums[booking[0] - 1] += booking[2];
            if (booking[1] < n) {
              // 右端点进行-操作
                nums[booking[1]] -= booking[2];
            }
        }
      // 对差分数组计算前缀和
        for (int i = 1; i < n; i++) {
            nums[i] += nums[i - 1];
        }
        return nums;
    }
}

最后

点赞,点赞,还TMD是点赞!