LeetCode 1109. 航班预订统计

109 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

一、题目描述:

1109. 航班预订统计 - 力扣(LeetCode)

这里有 n 个航班,它们分别从 1n 进行编号。

有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firstilasti )的 每个航班 上预订了 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
预订记录 110  10
预订记录 220  20
预订记录 325  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

二、思路分析:

适用:频繁对原始数组的某个区间的元素进行增减。

  1. 先对nums数组构造一个diff差分数组,diff[i] = nums[i] - nums[i - 1]。
  2. 再通过diff差分数组,可反推出原始数组:nums[i] = nums[i-1] + diff[i];
  3. 若想对区间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.
  4. 只花费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;
    }
}