leetcode
leetcode 1001 ~ 1050
拼车

拼车

难度:

标签:

题目描述

代码结果

运行时间: 17 ms, 内存: 16.4 MB


/*
 * 思路:
 * 1. 依然使用 toTrack 数组记录每个位置的乘客变化量。
 * 2. 通过 Stream 处理 trips 数组,记录乘客上车和下车的变化。
 * 3. 最后使用 Stream 计算乘客总数并验证是否超过容量。
 */
import java.util.Arrays;
import java.util.stream.IntStream;

public class CarPooling {
    public boolean carPooling(int[][] trips, int capacity) {
        int[] toTrack = new int[1001];
        Arrays.stream(trips).forEach(trip -> {
            toTrack[trip[1]] += trip[0];
            toTrack[trip[2]] -= trip[0];
        });
        return IntStream.of(toTrack).reduce(0, (currentPassengers, change) -> {
            currentPassengers += change;
            if (currentPassengers > capacity) throw new RuntimeException();
            return currentPassengers;
        }) <= capacity;
    }
}

解释

方法:

此题解采用的是差分数组的方法。首先,创建一个差分数组 dp,其长度为所有行程结束位置的最大值加一。对于每个行程 [numPassengers, from, to],在差分数组的 from 位置增加 numPassengers,表示这点有乘客上车;在 to 位置减去 numPassengers,表示这点有乘客下车。之后,计算差分数组的前缀和,得到每个位置的车上乘客数。如果任何位置的乘客数超过了车辆的容量,返回 false;否则,如果所有位置的乘客数都不超过容量,返回 true。

时间复杂度:

O(n + m)

空间复杂度:

O(m)

代码细节讲解

🦆
在差分数组方法中,为什么选择在`from`位置增加乘客数,在`to`位置减少乘客数?这种处理方式有何意义?
在差分数组中,增加`from`位置的乘客数表示乘客从该位置开始上车,而在`to`位置减少乘客数表示乘客在该位置下车并不再占用车辆空间。通过这种处理,差分数组可以简洁地表示在任何给定位置的乘客数变化。计算这个数组的前缀和可以直接得到任何位置的实时乘客总数,从而有效地模拟整个行程中车辆的乘客变化情况。
🦆
如果行程中有多个地点同时是上车点和下车点,代码中的差分数组处理是否会准确反映每个点的乘客变化?
差分数组的设计确保即使一个位置同时是多个行程的上车点和下车点,乘客的变化也能被准确记录。对于每个行程,在`from`位置增加乘客,在`to`位置减少乘客,无论这些操作发生多少次,都会被正确地累加或减去。因此,差分数组能够准确反映出每个地点的净乘客变化。
🦆
对于差分数组,计算前缀和时如何保证不会出现前缀和小于零的情况?这是否意味着车上始终有乘客?
在这个特定的场景中,前缀和小于零的情况理论上不应该发生,因为它会意味着车上的乘客数为负,这在现实中是不可能的。前缀和代表车上的乘客数量,它从零开始累加,只有在有乘客上车时才会增加。如果前缀和在任何时刻为负,这可能表明代码实现或输入数据有误。然而,前缀和为零并不意味着车上始终有乘客,它可能表示车是空的。
🦆
给出的代码示例中,为什么使用`max([el for el in accumulate(dp)])`来判断所有位置的乘客数是否超过容量,而不是逐一检查?
使用`max`函数配合`accumulate`(累加生成器)是一种效率较高的方式来找出任何时刻乘客数的最大值。这样可以在一次遍历中确定是否有任何时刻的乘客数超过了车辆的容量。如果逐一检查每个位置的乘客数,虽然也可行,但使用`max`可以更快地得出结果,尤其是在数据量大时更为高效。

相关问题

会议室 II

会议室 II