当前位置: 首页 > article >正文

【LeetCode】2332. 坐上公交的最晚时间

LeetCode 2332. 坐上公交的最晚时间

题目描述

详细的题目描述可见LeetCode对应的原题目。

简单来说,给定 A A A数组[10, 20] B B B数组[2, 17, 18, 19],数组A表示公交车的到达时间,B表示乘客到达车站的时间,还给定一个公交车的容量capacity,假定为 2 2 2,问乘客最晚在何时到达可以乘坐公交车。

显然对于上述样例,在t=10之前达到的只有2时刻到达的乘客,因此第一辆车在t=10出发,只携带第一个到达的乘客(显然,第一辆车有一个空位,因为公交车的容量为 2 2 2)。而第二辆车驶离的时间是t=20,在此之前还未离开且到达的乘客分别在t=17/18/19到达,只有t=17/18到达的乘客可以离开,因为公交车的容量为 2 2 2

对于上述样例,乘客可行的最晚到达时间是t=16,因为题目要求乘客的到达时间不可重复,公交车的驶离时间也是不重复的。

思路

拿到这道题目给我的第一感觉就是双指针,解决该问题也确实用到了双指针,但是五分钟内没想出来,参考了题解,发现自己确实遗漏了一些细节,遂在此对整题的思路进行记录。

首先,可以对公交车的驶离时间和乘客的到达时间进行一下排序,因为初始的输入可能是无序的,但数组中的元素应该是有序的。

之后,便可以开始设计算法解决这道题目。

此处使用双指针,一个指针arrive指向公交车驶离时间的数组buses,而另一个指针pos指向乘客的到达时间数组passengers。对每一个公交车驶离的时间进行遍历,在遍历的每一步当中,需要对乘客到达时间的指针进行修改。在每一次迭代的初始时,设置一个变量space = capacity用于表示当前这辆车还剩下多少个空位。当公交车满载时,即使乘客已经达到也无法上车,按照先来后到没上车的乘客将登上下一辆车。

分析完问题之后,这道题目的双指针更新边界也就非常明朗了,可以抽象为如下代码:

while(space > 0 && pos < passengers.size() && passengers[pos] <= arrive) {
	space --;	// 当前车辆的位置减一
	pos ++;		// 满足条件的乘客上车
}

需要注意的是条件pos < passengers.size()一定是在passengers[pos] <= arrive之前的,因为按照C/C++条件运算符的优先级,对于&&运算,从左至右只要有一个条件不满足,那么直接返回false,如果先判断passengers[pos] <= arrive的话,此时的pos可能越界,即已经遍历完所有的passengers了。

下一步是对答案就行更新。乘客的最晚到达时间分为两种情况,第一种情况是最后一辆车还没有坐满,这是最理想的情况,乘客直接在最后一辆车的驶离时刻到达即可。第二种情况较为复杂,即最后一辆车也坐满了,它的最晚到达时间只能早于passengers当中从后往前找到的某个值,可以先令它为passengers[pos],再向前找到满足条件的值。

需要注意的是,根据刚才的分析,指针pos会指向满足迭代条件的下一个值(因为这样才会使循环达到条件而停止),因此在对答案进行更新之前需要先对pos --

最后一辆车的剩余位置为space,按照刚才的分析,答案res = buses.back() if space > 0 else passengers[pos]。如果res = passengers[pos],由于题目要求乘客不能同时到达,必须向前寻找满足条件的值,由于乘客在passengers中可能接连到达,因此使用下述逻辑来得到最终的res

while(pos >= 0 && passengers[pos] == res) {
	res --;
	pos --;
}

此处使用pos >= 0不必考虑边界情况,因为题目要求中明确指出passengers的值不会小于 2 2 2,意味着res最晚也可以是 1 1 1

C++的完整实现如下:

class Solution {
public:
    int latestTimeCatchTheBus(vector<int>& buses, vector<int>& passengers, int capacity) {
        sort(passengers.begin(), passengers.end());
        sort(buses.begin(), buses.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 res = space > 0 ? buses.back() : passengers[pos];
        while(pos >= 0 && res == passengers[pos]) {
            res --;
            pos --;
        }
        return res;
    }
};

Go的实现如下:

func latestTimeCatchTheBus(buses []int, passengers []int, capacity int) int {
    sort.Ints(buses)
    sort.Ints(passengers)

    space, pos := 0, 0
    for _, arrive := range(buses) {
        space = capacity
        for space > 0 && pos < len(passengers) && passengers[pos] <= arrive {
            space --
            pos ++
        }
    }

    pos --
    res := buses[len(buses)-1]
    if space <= 0 {
        res = passengers[pos]
    }

    for pos >= 0 && res == passengers[pos] {
        pos --
        res --
    }
    return res
}

【又学到了一些Go语法上的新知识,比如使用sort.Ints(buses)可以直接对整型数组进行排序】


http://www.kler.cn/a/310171.html

相关文章:

  • 三种单例实现
  • 《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>
  • 数据安全、信息安全、网络安全区别与联系
  • Kettle——CSV文件转换成excel文件输出
  • 【Vue】Vue3.0(二十)Vue 3.0 中mitt的使用示例
  • 后悔没早点知道,Coze 插件 + Cursor 原来可以这样赚钱
  • AI驱动TDSQL-C Serverless 数据库技术实战营-ai学生选课系统数据分析
  • 基于Java+SpringMVC+vue+element宠物管理系统设计实现
  • Python安装虚拟环境Conda
  • Nacos未授权访问
  • 情感计算领域可以投稿的期刊与会议
  • C++ | Leetcode C++题解之第415题字符串相加
  • .NET 框架版本年表
  • ChatGPT对话训练数据采集渠道有哪些
  • JavaScript 的 DOM 技术
  • 如何划分 PostgreSQL 数据库权限
  • BOE(京东方)领先科技赋能体育产业全面向新 以击剑、电竞、健身三大应用场景诠释未来健康运动新生活
  • AI之所以会具有巨大的作用,体现在它对于产业的深度影响和改造上
  • FEAD:fNIRS-EEG情感数据库(视频刺激)
  • 83.static关键字
  • 《Effective C++》第三版——构造、析构、赋值运算
  • 视频美颜SDK与直播美颜工具的实现原理与优化方案
  • JS 常见的排序算法及比较
  • 进程优先级和环境变量
  • 【算法】BFS系列之 FloodFill 算法
  • 算法:TopK问题