力扣(leetcode)每日一题 2332 坐上公交的最晚时间

题目:

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

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

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

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

注意:数组 buses 和 passengers 不一定是有序的。

示例 1:

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

思路

这个题目相当恶心。当时想到了两种做法,一种是贪心,也是题解的方法,但是想到一个精妙的模型进行抽象,只能不断的补逻辑漏洞。还有一种是二分法。

二分法没有尝试,我看题解有的。

解法1 自己尝试出来的

自己的贪心写法试了很多次,大思路是对的,但是就是有考虑不全的地方

在这里插入图片描述
乘客是从小到大排序的,汽车也是从小到大排序的。
当乘客上车不能满足当前汽车cur需求,就需要切换到下一辆next
然后对cur进行求解。 汽车cur的求解分3种情况。
第一种,没有人,就是取汽车出发时间作为最大值,
第二种没有坐满人,这时候需要从出发时间倒退,如果说出发时间20,乘客没有20,就是取20,乘客有20,就需要找有无乘客是19出发的,如果没有,19就可以作为出发点。必然可以更新最大值。
第三种,坐满了人,其实还是从后往前推,看看能不能挤进来座位。(区别上一种可以直接从汽车出发点逆推)
特殊情况,第一个乘客赶不上最后的车,贪心最后一辆车的出发时间
if (passengers[0] > buses[buses.length - 1]) { return buses[buses.length - 1]; }
另外还有考虑,车发完了,人还没有完,提前返回,人发完了,车还没有结算,继续结算
还有最小值从 int max = passengers[0] - 1 第一个乘客减1开始搭配 max = Math.max(max, buses[j]); 是因为坐满的逻辑有缺陷,需要补上一位 比如。满车 10,11,12 看看能不能补上贪心9 因为没有考虑到,所以才有这么丑陋的代码

总之方向是对的,但是自己思考的贪心的逻辑是混乱的

public static int latestTimeCatchTheBus(int[] buses, int[] passengers, int capacity) {Arrays.sort(buses);Arrays.sort(passengers);// 如果第一个乘客赶不上最后一班车。那么直接返回最后一班车的时间if (passengers[0] > buses[buses.length - 1]) {return buses[buses.length - 1];}int max = passengers[0] - 1;int j = 0;List<Integer> list = new ArrayList<>();for (int i = 0; i < passengers.length; i++) {int passenger = passengers[i];while (buses[j] < passenger || list.size() == capacity) {  // 时间上不合适,寻找下一辆车// 如果满员if (capacity == list.size()) {// 看一下前面有没有空间可以插入for (int k = 0; k < list.size(); k++) {Integer pre = list.get(k);if (pre > 0 && passengers[pre - 1] + 1 < passengers[pre]) {max = passengers[pre] - 1;  }}list = new ArrayList<>();} else if (list.isEmpty()) {// 如果汽车上是空的话,就是说我要贪心坐上这辆车出发的时间max = Math.max(max, buses[j]); } else { // 如果没有满员 或者如果为空。没有满员但是是掐点到的。// 从后往前遍历。int need = buses[j];int flag = 0;for (int k = list.size() - 1; k >= 0; k--) {Integer i1 = list.get(k);if (passengers[i1] != need) {max = need;flag = 1;break;}need--;}if (flag == 0 && list.get(0) > 0 && passengers[list.get(0) - 1] + 1 != passengers[list.get(0)]) {max = need;}list = new ArrayList<>();}j++;// 如何结算if (j == buses.length) {return max;}}list.add(i);}// 最后还要再结算一次if (capacity == list.size()) { // 如果满员//  看一下前面有没有空间可以插入for (int k = 0; k < list.size(); k++) {Integer pre = list.get(k);if (pre > 0 && passengers[pre - 1] + 1 < passengers[pre]) {max = passengers[pre] - 1; // 更新first,可以放在最前面}}j++;} else if (list.isEmpty()) {// 如果是空的话,就是说我要坐上这辆车最晚的时间// 20点的车  就20点上车max = Math.max(max, buses[j]);j++;} else { // 如果没有满员 或者如果为空。没有满员但是是掐点到的。// 从后往前遍历。int need = buses[j];int flag = 0;for (int k = list.size() - 1; k >= 0; k--) {Integer i1 = list.get(k);if (passengers[i1] != need) {max = need;flag = 1;break;}need--;}if (flag == 0 && list.get(0) > 0 && passengers[list.get(0) - 1] + 1 != passengers[list.get(0)]) {max = need;}j++;}// 如果汽车没有遍历完,遍历汽车while (j < buses.length) {max = Math.max(max, buses[j]);j++;}return max;}
解法2 官方的

先不断的塞人
如果说。到了最后一辆车,人都挤满了。刚好挤满。就顺着人倒退,找第一个出现的空隙。(比如,乘客有 22,21,20,19,17 就可以找到空袭18返回)
如果没有坐满,直接返回最后一辆车的数值

public int latestTimeCatchTheBus2(int[] buses, int[] passengers, int capacity) {Arrays.sort(buses);Arrays.sort(passengers);int pos = 0;int space = 0;for (int arrive : buses) {space = capacity;while (space > 0 && pos < passengers.length && passengers[pos] <= arrive) {space--;pos++;}}pos--;// space多余0 说明还有位置,就去最后一班车。否则,说明没有空位,只能倒推int lastCatchTime = space > 0 ? buses[buses.length - 1] : passengers[pos];while (pos >= 0 && passengers[pos] == lastCatchTime) {pos--;lastCatchTime--;}return lastCatchTime;}// 如果有空隙可以直接进去。如果没有空袭,需要从后往前遍历
总结

这就像是初级程序员和高级程序员写业务代码。高级程序员直核心,逻辑简单明了。初级程序员逻辑弯弯绕绕,各种变量,各种补丁,无用的判断分支。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145642.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于&#xff0c;一些 WAF 产品处于降低误报考虑&#xff0c;对用户上传文件的内 容不做匹配&#xff0c;直接放行 0、环境 环境&#xff1a;两台服务器&#xff0c;一台配置宝塔面板&#xff0c;一台配置长亭雷池WAF 思路主要围绕&#xff1a;m…

【渐冻勇士的营养秘籍!这些营养素让爱更坚强】

Hey小伙伴们~&#x1f44b; 今天我们来聊聊一个温暖而坚强的话题——渐冻症患者的营养补充攻略&#xff01;&#x1f4aa; 在这个充满挑战的路上&#xff0c;合理的营养摄入就像是他们最坚实的盔甲&#xff0c;让爱与希望的光芒更加耀眼。✨ &#x1f308; ‌蛋白质&#xff1…

Altium Designer(AD)百度云下载与安装(附安装步骤)

在我们日常使用当中&#xff0c;Altium designer常常也被简称为AD&#xff0c;是一款一体化的电子产品开发系统软件&#xff0c;主要运行在Windows操作系统上。 我们通过Altium designer把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技…

商业终端架构技术-未来之窗行业应用跨平台架构

未来之窗行业应用跨平台架构 以下是对未来之窗行业应用跨平台架构中客户端的稳定优势和网页跨平台性质的扩展列举&#xff1a; 一、客户端的稳定优势&#xff1a; 1. 离线可用性 - 即使在没有网络连接的…

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿 人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;量化投资已逐渐成为金融行业的新趋势&#xff0c;对专业人才的需求日益迫切。本文将深入探讨一项针对AI与量化投资的人才培养计划&#xff0c;旨在为金融专业…

电气自动化入门05:三相异步电动机的正反转点动控制电路

视频链接&#xff1a;3.2 电工知识&#xff1a;三相异步电动机的正反转点动控制电路_1_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p6&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.断路器及其选型 1.1断路器定义、分类、表示符号 1.2.断路器功能、…

克隆GitHub仓库中的一个文件夹

要只克隆GitHub仓库中的一个文件夹&#xff0c;你可以使用 git sparse-checkout 功能。以下是具体步骤&#xff1a; 克隆仓库&#xff08;使用 --no-checkout 选项&#xff0c;避免下载所有内容&#xff09;&#xff1a; git clone --no-checkout <仓库地址> 进入克隆的…

[产品管理-29]:NPDP新产品开发 - 27 - 战略 - 分层战略与示例

目录 1. 公司战略 2. 经营战略 3. 创新战略 4. 新产品组合战略 5. 新产品开发战略 战略分层是企业规划和管理的重要组成部分&#xff0c;它涉及不同层级的战略制定和实施。以下是根据您的要求&#xff0c;对公司战略、经营战略、创新战略、新产品组合战略、新产品开发战略…

【CSS Tricks】如何做一个粒子效果的logo

效果展示 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>粒子效果Logo</title>…

uniapp使用uview2上传图片功能

官网地址Upload 上传 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 前提&#xff0c;需要下载vuew2插件 <view class"upload"><view class"u-demo-block__content"><view class"u-page__upload-item"&…

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制&#xff08;防止网络波动&#xff09;2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】 适用于:V200R008至V200R019C00版本的AC,以及有空闲以太网口的AP。 说明:本示例基于“直连二层组网直接转发【AP+AC+出口网关】”场景来介绍如何增加AP下行口有线接入。 业务需求…

SPI 详解

介绍 串行外设接口是微控制器用来与外设&#xff08;如 SRAM、SD 卡、移位寄存器、传感器等&#xff09;通信的最常见通信协议之一。它是一种同步、全双工、基于主从的协议。它支持高速数据传输&#xff0c;并且 SPI 协议中的数据速度 (bps) 和时钟频率 (Hz) 之间存在直接关系…

[Redis][Hash]详细讲解

目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…

鹏哥C语言复习——函数栈帧的创建和销毁

目录 演示用代码&#xff1a; 提示&#xff1a;后文讲解时后缀为h的指的是16进制表示 疑惑1&#xff1a;自定义函数、库函数都是在main函数内部调用&#xff0c;那么是什么调用了main函数呢&#xff1f; 疑惑2&#xff1a;如何观察ebp、esp等寄存器的运行&#xff1f; 疑惑…

提升效率的AI工具集 - 轻松实现自动化

在这个快节奏、高效率的社会中&#xff0c;我们每个人都渴望能够找到提升工作效率的捷径。幸运的是&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;越来越多的AI工具涌现出来&#xff0c;为我们提供了强大的支持。这些工具不仅能够帮助我们提高…

算法-分治和逆序

分治法&#xff08;Divide and Conquer&#xff09;是一种重要的算法设计范式&#xff0c;它通过将复杂的问题分解成更小、更易于管理和解决的子问题&#xff0c;然后递归地解决这些子问题&#xff0c;最后将子问题的解合并以得到原问题的解。分治法通常用于排序、搜索、数学计…

基于STM32F103C8T6单片机的DDS信号源设计

本设计能够输出三角波信号、方波信号和正弦波信号,主要由STM32F103C8T6最小核心板、电源供电电路模块、AD9833电路模块、矩阵按键电路模块、LCD1602液晶显示模块等组成。在设计中&#xff0c;使用STM32F103C8T6作为控制芯片&#xff0c;结合LCD1602液晶显示器&#xff0c;矩阵键…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…