【差分数组】LeetCode 1094. 拼车

题目 车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向) 给定整数 capacity 和一个数组 trips , trip[i] = [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客,接

题目

车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向

给定整数 capacity 和一个数组 trips ,  trip[i] = [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客,接他们和放他们的位置分别是 fromi 和 toi 。这些位置是从汽车的初始位置向东的公里数。

当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false

示例 1:

输入:trips =[[2,1,5],[3,3,7]], capacity = 4
输出:false

示例 2:

输入:trips = [[2,1,5],[3,3,7]], capacity = 5
输出 true

提示:

  • 1 <= trips.length <= 1000
  • trips[i].length == 3
  • 1 <= numPassengersi <= 100
  • 0 <= fromi < toi <= 1000
  • 1 <= capacity <= 105

思路

只需要将每个站点坐车的人数统计起来(即fromto - 1),如果有超过车子容量的情况,即为false,否则为true

解法

暴力

可以直接开一个长度为1005的数组,再对每一组乘客数量在每站进行相加,判断是否有超出容量的即可。

class Solution {
public:
    bool carPooling(vector<vector<int>>& trips, int capacity) {
        int site[1005] = {0};
        for (int i = 0; i < trips.size(); ++i) {
            for(int j = trips[i][1]; j <= trips[i][2] - 1; ++j) {
                site[j] += trips[i][0];
                if (site[j] > capacity) return false;
            }
        }

        return true;
    }
};
  • 时间复杂度: O(n2)

差分数组

我们可以思考,乘客数量是只有在上下车才会发生变化,其余时间都不会发生变化,那么此时是否可以维护两个点的数据呢?

我们就可以想到差分:

有一个数组为[1,2,2,3,4,4],我们用后项减去前项,可以得到[1,1,0,1,1,0],这个就是差分数组,此时就会发现只有在数据发生变化的时候才不为0,为ta的变化值。
明白了这个道理后,我们把差分数组做一个前缀和相加,可以得到[1,2,2,3,4,4],即我们原来的数组

我们再对差分数组的第2和第5项加2,得到的是[1,3,0,1,3,0],对新数组再进行一个前缀和相加得到[1,4,4,5,8,8],此时就可以发现:

对比原数组,我们在第二项往后都加了2,在第五项往后再加了2

这就是差分数组。

回到题目,利用差分的思维去思考,我们只需要在上车from处数据加上乘客数,在下车to处减去乘客数,再在最后将差分数组做前缀和相加,与车容量比较,那不就可以达到我们的效果了?

优化后的代码:

class Solution {
public:
    bool carPooling(vector<vector<int>>& trips, int capacity) {
        int site[1005] = {0}; //此数组为差分数组
        for (int i = 0; i < trips.size(); ++i) {
            site[trips[i][1]] += trips[i][0];
            site[trips[i][2]] -= trips[i][0];
        }
        int sum = 0;
        for (int i = 1; i < 1005; ++i) {
            sum += site[i - 1];
            if (sum > capacity) return false;
        }
        return true;
    }
};
  • 时间复杂度:O(n)

总结

当遇到只有始末状态量变化的线性关系时,可以考虑使用差分。

Comment