拼车【!】
第一次接触到【差分】的概念
差分 举例
定义和性质
对于本题来说,运用差分的方法,可以变得十分简单:
创建一个d[1001]的数组 d[i] ,i代表第i个地点
遍历trips[i],将每个trips[i]中的 from 和to 对应到 d[from] 和d[to]中,并将值赋为passagers和 -passagers
这样就形成了一个差分数组d
将d从左到右累加 就转换成了 能够反映每个地点乘客人数信息 的数组
如
注:
维护路程大小的数组 在路程太长时耗费空间
所以可以使用TreeMap进行预排序,然后遍历map中的值 ,模拟差分数组的累加
代码
class Solution10 {
//用哈希表记录,耗时,耗费空间
public boolean carPooling1(int[][] trips, int capacity) {
Map<Integer,Integer> from=new HashMap<>();
Map<Integer,Integer> to=new HashMap<>();
int curSum=0;
int maxTo=trips[0][2];
for(int i=0;i<trips.length;i++){
from.put(trips[i][1],trips[i][0]+from.getOrDefault(trips[i][1],0));
to.put(trips[i][2],trips[i][0]+to.getOrDefault(trips[i][2],0));
maxTo=Math.max(maxTo,trips[i][2]);
}
for(int i=1;i<=maxTo;i++){
curSum+=from.getOrDefault(i,0)-to.getOrDefault(i,0);
if(curSum>capacity){
return false;
}
}
return true;
}
//差分方法:数组
public boolean carPooling2(int[][] trips, int capacity) {
//创建一个大小为0-1000的差分数组
int[] d=new int[1001];
for(int i=0;i<trips.length;i++){
//from 的对应下标 值加人数
d[trips[i][1]]+=trips[i][0];
//to 的对应下标 值减人数
d[trips[i][2]]-=trips[i][0];
}
int sum=0;
for(int i=0;i<d.length;i++){
sum+=d[i];
if(sum>capacity){
return false;
}
}
return true;
}
//差分方法:排序
public boolean carPooling3(int[][] trips, int capacity) {
TreeMap<Integer,Integer> d=new TreeMap<>();
for(int[] t:trips){
int num=t[0];int from=t[1]; int to=t[2];
d.put(from,d.getOrDefault(from,0)+num);
d.put(to,d.getOrDefault(to,0)-num);
}
//遍历treeMap,模拟差分数组的递推
int curPeople=0;
for(int num:d.values()){
curPeople+=num;
//如果当前人数大于容量,返回false
if(curPeople>capacity){
return false;
}
}
return true;
}
}
第一次的暴力解法
差分数组
TreeMap排序后模拟差分