前言
假設你是一位順風車司機,車上最初有
capacity
個空座位可以用來載客。由於道路的限制,車 只能 向一個方向行駛(也就是說,不允許掉頭或改變方向,你可以將其想象爲一個向量)。這兒有一份行程計劃表
trips[][]
,其中trips[i] = [num_passengers, start_location, end_location]
包含了你的第i
次行程信息:
- 必須接送的乘客數量;
- 乘客的上車地點;
- 以及乘客的下車地點。
這些給出的地點位置是從你的 初始 出發位置向前行駛到這些地點所需的距離(它們一定在你的行駛方向上)。
請你根據給出的行程計劃表和車子的座位數,來判斷你的車是否可以順利完成接送所用乘客的任務(當且僅當你可以在所有給定的行程中接送所有乘客時,返回
true
,否則請返回false
)。示例1:
輸入:trips = [[2,1,5],[3,3,7]], capacity = 4 輸出:false
示例2:
輸入:trips = [[2,1,5],[3,3,7]], capacity = 5 輸出:true
示例3:
輸入:trips = [[2,1,5],[3,5,7]], capacity = 3 輸出:true
示例4:
輸入:trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11 輸出:true
提示:
- 你可以假設乘客會自覺遵守 “先下後上” 的良好素質
trips.length <= 1000
trips[i].length == 3
1 <= trips[i][0] <= 100
0 <= trips[i][1] < trips[i][2] <= 1000
1 <= capacity <= 100000
解題思路
本題難度爲中等,主要是需要注意以下幾點:
- 多段路程中可能存在部分乘客下車的情況
- 需要考慮車子剩餘的空座位
- 可能會存在多段路程的乘客同一個下車地點
我的解題思路如下:
- 將所有行程按照上車地點從小到大排序
-
遍歷所有行程,模擬車子行駛,使用
TreeMap
記錄有某個下車地點下車人數,按照以下邏輯處理- 如果當前沒有乘客在車上(
TreeMap
爲空),則判斷本次行程是否能夠讓乘客都坐下,若是將本次的行程的下車地點爲key
,乘客數目爲value
存入到TreeMap
中;否則直接返回false
- 如果當前有乘客(
TreeMap
不爲空),則檢查所有上車乘客是否存在需要下車的人(TreeMap
中的key
下車地點小於或等於本次行程的上車地點)並將其移除。然後判斷車子當前是否有足夠座位載客(TreeMap
的value
之和加上本次行程的乘客數是否不大於車子總座位數),如果足夠則加入本次行程(TreeMap
記錄下來,如果存在相同下車地點,則人數相加),否則返回false
- 如果當前沒有乘客在車上(
實現代碼
/**
* 1094. 拼車
*
* @param trips
* @param capacity
* @return
*/
public boolean carPooling(int[][] trips, int capacity) {
boolean flag = true;
// 根據上車地點從小到大排序
Arrays.sort(trips, Comparator.comparingInt(o -> o[1]));
// key爲下車地點,value爲乘客數目
TreeMap<Integer,Integer> capacityMap=new TreeMap<>();
for (int i = 0; i < trips.length; i++) {
// 乘客數量
int numPassengers = trips[i][0];
// 上車地點
int startLocation = trips[i][1];
// 下車地點
int endLocation = trips[i][2];
if(!capacityMap.isEmpty()){
// 處理java.util.ConcurrentModificationException
Set<Integer> locationSet = new TreeSet<>();
locationSet.addAll(capacityMap.keySet());
Iterator<Integer> it=locationSet.iterator();
while (it.hasNext()){
Integer lastEndLocation=it.next();
if(lastEndLocation<=startLocation){ // 到達終點,乘客下車
capacityMap.remove(lastEndLocation);
}
}
// 計算當前總乘客數
int totalCap=capacityMap.values().stream().mapToInt(Integer::intValue).sum()+numPassengers;
if(totalCap>capacity){ // 車子座位不足
flag=false;
break;
}
if(capacityMap.containsKey(endLocation)){ // 是否存在同一個下車地點的乘客
capacityMap.put(endLocation,capacityMap.get(endLocation)+numPassengers);
}else{
capacityMap.put(endLocation,numPassengers);
}
}else{
if (numPassengers > capacity) { // 車子座位不足
flag = false;
break;
}
capacityMap.put(endLocation,numPassengers);
}
}
return flag;
}