坐上公交的最晚时间

2024-09-18

题目:

给你一个下标从 0 开始长度为 n 的整数数组 buses ,其中 buses[i] 表示第 i 辆公交车的出发时间。同时给你一个下标从 0 开始长度为 m 的整数数组 passengers ,其中 passengers[j] 表示第 j 位乘客的到达时间。所有公交车出发的时间互不相同,所有乘客到达的时间也互不相同。

给你一个整数 capacity ,表示每辆公交车 最多 能容纳的乘客数目。

每位乘客都会搭乘下一辆有座位的公交车。如果你在 y 时刻到达,公交在 x 时刻出发,满足 y <= x 且公交没有满,那么你可以搭乘这一辆公交。最早 到达的乘客优先上车。

返回你可以搭乘公交车的最晚到达公交站时间。你 不能 跟别的乘客同时刻到达。

注意:数组 busespassengers 不一定是有序的。

示例 1:

输入:buses = [10,20], passengers = [2,17,18,19], capacity = 2
输出:16
解释:
第 1 辆公交车载着第 1 位乘客。
第 2 辆公交车载着你和第 2 位乘客。
注意你不能跟其他乘客同一时间到达,所以你必须在第二位乘客之前到达。

示例 2:

输入:buses = [20,30,10], passengers = [19,13,26,4,25,11,21], capacity = 2
输出:20
解释:
第 1 辆公交车载着第 4 位乘客。
第 2 辆公交车载着第 6 位和第 2 位乘客。
第 3 辆公交车载着第 1 位乘客和你。

提示:

  • n == buses.length
  • m == passengers.length
  • 1 <= n, m, capacity <= 105
  • 2 <= buses[i], passengers[i] <= 109
  • buses 中的元素 互不相同
  • passengers 中的元素 互不相同

示例 1:

输入:routes = [[1,2,7],[3,6,7]], source = 1, target = 6
输出:2
解释:最优策略是先乘坐第一辆公交车到达车站 7 , 然后换乘第二辆公交车到车站 6 。 

示例 2:

输入:routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
输出:-1

提示:

  • 1 <= routes.length <= 500.
  • 1 <= routes[i].length <= 105
  • routes[i] 中的所有值 互不相同
  • sum(routes[i].length) <= 105
  • 0 <= routes[i][j] < 106
  • 0 <= source, target < 106

思路:

由于最早到达的乘客优先上车,为了方便模拟,我们将公交车到达的时间和乘客到达的时间按照先后顺序进行排序。设第 i 班公交车到达的时间为 buses[i],此时未上车且在 buses[i] 时刻之前到达的乘客按照时间先后顺序依次上车,直到车辆载客人数达到上限 capacity 为止,则继续模拟第 i + 1 班公交车乘客上车,直到所有的车辆均模拟完毕。

此时记录最后一班公交车发车时的空位数为 space,此时有以下两种情形:
	如果此时 space > 0,则表示最后一班公交车发车时车上还有空位,这意味着我们最晚可以在最后一班公交发车时刻到站即可,由于不能跟别的乘客同时刻到达,此时从最后一班发车时刻 buses[n − 1] 开始向前找到一个没有乘客到达的时刻即可;
	如果此时满足 space = 0,则表示最后一班公交车发车时车上没有空位,这意味着我们最后一个上车的乘客上车以后载客已满,此时我们从最后一个上车乘客的到达时间往前找到一个没有乘客到达的时刻即可,如果到达时间晚于最后一个上车的乘客的到达时间,则一定无法乘车。

代码:

class Solution {
public:
    int latestTimeCatchTheBus(vector<int>& buses, vector<int>& passengers, int capacity) {
        sort(buses.begin(), buses.end());
        sort(passengers.begin(), passengers.end());
        int pos = 0;
        int space = 0;
        for (int arrive : buses) {
            space = capacity;
            while (space > 0 && pos < passengers.size() && passengers[pos] <= arrive) {
                pos++;space--;
            }
        }
        pos--;
        int lastCatchTime = space > 0 ? buses.back() : passengers[pos]; // 要么是最后一班车到达时间,要么是最后一个坐上车的乘客的到达时间
        while (pos >= 0 && passengers[pos] == lastCatchTime) {
            pos--;
            lastCatchTime--;
        }
        return lastCatchTime;
    }
};