题解 | 「力扣」第 1109 题:航班预订统计(中等、差分数组)

228 阅读1分钟

摘要:对数组执行前缀和操作得到「前缀和」数组,对「前缀和」数组执行「差分」操作得到「原始数组」。本题通过「输入数据」在「差分数组」上的操作,进而求解「前缀和」数组,得到「原始数组」。

差分知识点

输入数组a0,a1,,an1a_0,a_1,\cdots,a_{n-1}

定义「差分数组」:b0=a0,b1=a1a0,,bn1=an1b_0 = a_0,b_1 = a_1 - a_0,\cdots,b_{n-1} = a_{n-1},数组 bb 的前缀和就是数组 aa

给数组 aa 的区间 [left..right] 每个数都加上 xx ,数组 bb 的数值发生变化的只有:bleftb_{left}brightb_{right}。这是因为:

  • bleft=aleft+xaleft1b_{left} = a_{left} + x - a_{left - 1} ,有变化。
  • bright+1=aright+1(aright+x)b_{right + 1} = a_{right + 1} - (a_{right} + x) ,有变化。

其余 bib_ii[left+1..right]i \in [left + 1..right] 的元素都没有变化,这是因为

bi=ai+x(ai1+x)b_{i} = a_{i} + x - (a_{i - 1} + x),都没有变化。

注意:差分数组的最后一个数不能要

理解题意

输入数组和输出数组可以通过下面的图来理解题意。

image.png

解题思路

本题通过「输入数据」在「差分数组」上的操作,进而求解「前缀和」数组,得到「原始数组」。

参考代码

public 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;
    }
}

这里要注意两个细节:

  • 细节 1:处理左边界的时候,下标有一个偏移,所以是 nums[booking[0] - 1] += booking[2];
  • 细节 2:处理右边界的时候,由于处理的是 right + 1,所以不用减 11(这里没有说得很清楚,相信大家可以明白意思)。

我讲解的算法特别适合新手朋友。欢迎大家关注我的公众号「算法不好玩」,B 站关注「liweiwei1419」。