leetcode
leetcode 1051 ~ 1100
航班预订统计

航班预订统计

难度:

标签:

题目描述

代码结果

运行时间: 46 ms, 内存: 27.1 MB


/*
 * 题目思路:
 * 使用Java Stream的方式实现类似的逻辑。
 * 1. 使用一个初始大小为 n 的数组来存储结果。
 * 2. 使用流处理每一个预订记录。
 * 3. 在第一个索引处加 seats,在最后一个索引的后一个位置减 seats。
 * 4. 最后使用累加流来更新结果。
 */

import java.util.Arrays;

public int[] corpFlightBookings(int[][] bookings, int n) {
    int[] answer = new int[n];
    Arrays.stream(bookings).forEach(booking -> {
        int first = booking[0];
        int last = booking[1];
        int seats = booking[2];
        answer[first - 1] += seats;
        if (last < n) {
            answer[last] -= seats;
        }
    });
    // 累积求和
    Arrays.parallelPrefix(answer, Integer::sum);
    return answer;
}

解释

方法:

题解使用了差分数组的技巧来解决航班预订统计的问题。首先初始化一个长度为n的数组nums,所有元素初始值为0。对于每条预订记录[l, r, x],在nums的l-1位置加上x(代表从第l个航班开始增加x个座位),并在r位置减去x(代表第r+1个航班开始减少x个座位,这样就不会影响第r个航班)。这样设置后,nums数组的每个位置仅表示从当前位置开始的增量变化。最后,使用累积和函数itertools.accumulate对nums进行处理,得到每个航班的总座位数。

时间复杂度:

O(m + n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在差分数组nums中要在r位置减去x,而不是在r+1位置操作?
在差分数组中,我们增加x到l-1位置以增加从第l个航班开始的座位数。为了确保这个增加只影响到第r个航班,我们需要在第r个航班之后的位置(即r位置,因为数组索引从0开始)减去x。这样操作后,累积和计算时,从第r+1个航班开始,增加的座位数就会被抵消,不影响第r+1个及之后的航班。如果在r+1位置操作,将会导致第r个航班的座位数没有被正确减少。
🦆
差分数组的方法与直接遍历bookings数组更新每个航班的座位数相比,具体有哪些优势?
差分数组的方法主要优势在于效率。使用差分数组只需要对每个预订操作进行常数时间的更新(即在l-1和r位置各一次操作),然后使用一次线性时间的累积和计算来获取最终结果。总体时间复杂度是O(n + k),其中k是预订记录数量,n是航班数量。相比之下,如果直接遍历bookings数组更新每个航班的座位数,则每个预订可能需要O(n)的时间来更新航班座位,对所有预订操作复杂度可能达到O(k*n),在k和n都较大时效率会显著降低。
🦆
如果预订记录中的firsti为1,对nums数组的操作有什么特殊考虑吗?
如果预订记录中的firsti为1,即预订从第一个航班开始,则在差分数组nums中,我们会在0索引位置(即第一个航班)增加座位数。由于没有更早的航班,因此不需要在负索引位置操作,只需要保证在结束航班后正确减少座位数即可。这是因为差分数组的设计自然适应了从数组第一个位置开始的变化。
🦆
在差分数组nums完成所有预订记录的处理后,为什么累积和能准确地反映每个航班的总座位数?
差分数组记录的是从一个航班到下一个航班的座位数变化量。通过对这些变化量进行累积求和,可以有效地构建出每一个航班的实际座位数。累积和的结果是从第一个航班开始,逐步加上每个航班的变化量,因此能够准确地反映每一个航班在所有预订操作后的总座位数。这是一种将局部修改信息整合为全局视图的高效方法。

相关问题