题目
车上最初有 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
思路
只需要将每个站点坐车的人数统计起来(即from
到to - 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)
总结
当遇到只有始末状态量
变化的线性关系时,可以考虑使用差分。