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

news2024/12/24 3:06:55
题目:

给你一个下标从 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.coloradmin.cn/o/2151644.html

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

相关文章

(七)使用SoapUI工具调用WebAPI

1.调用一个无参数的GET请求 [HttpGet(Name "GetWeatherForecast")]public IEnumerable<WeatherForecast> Get(){return Enumerable.Range(1, 5).Select(index > new WeatherForecast{Date DateTime.Now.AddDays(index),TemperatureC Random.Shared.Next(…

QFramework v1.0 使用指南 更新篇:20240918. 新增 BindableList

20240918. 新增 BindableList BindableProperty 很好用&#xff0c;但是不支持 List 等集合。 而 Bindable List 功能群友呼吁了很久了。 应群友要求&#xff0c;笔者实现了 Bindable List。 基本使用方式如下: using System; using UnityEngine; using UnityEngine.UI;na…

最新版本TensorFlow训练模型TinyML部署到ESP32入门实操

最新版本TensorFlow训练模型TinyML入门实操 1.概述 这篇文章介绍微型嵌入式设备的机器学习TinyML&#xff0c;它们的特点就是将训练好的模型部署到单片机上运行。 2.TensorFlow深度学习原理 TensorFlow开源项目是由google研发的一个嵌入式机器学习工具&#xff0c;通过调用…

智慧安防监控EasyCVR视频汇聚管理平台如何修改视频流分辨率?

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端监控设备进行统一集中接入与汇聚管理。EasyCVR平台支持H.264/H.265视频压缩技术&#xff0c;可在4G/5G/WIFI/宽带等网络环境下&#xff0c;传输720P/1080P/2K/4K高清视频。视频流经平台处理后&#xff0…

高质量的翻译:应用程序可用性和成功的关键

在日益全球化的应用市场中&#xff0c;开发一款优秀的产品只是成功的一半。另一半&#xff1f;确保你的用户&#xff0c;无论他们在哪里或说什么语言&#xff0c;都能无缝理解和使用它。这就是高质量翻译的用武之地——不是事后的想法&#xff0c;而是应用程序可用性和最终成功…

如何写一个自动化Linux脚本去进行等保测试--引言

#我的师兄喜欢给我的休闲实习生活加活&#xff0c;说是让我在实习期间写一个自动化脚本去进行等保测试。呵呵哒。 怎么办呢&#xff0c;师兄的指令得完成&#xff0c;师兄说让我使用Python完成任务。 设想如下&#xff1a; 1、将Linux指令嵌入到python脚本中 2、调试跑通 …

C++11——function与bind

包装器 function包装器function的介绍function的使用function的使用场景function的意义 bind包装器bind的介绍bind的使用 function包装器 function的介绍 function是用来包装函数的&#xff0c;所以叫做包装器或者适配器&#xff0c;fuction的本质其实是一个类模板。 functio…

Mac使用gradle编译springboot-2.7.x源码

1 开发环境&#xff1a; JDK8 ideaIU-2024.2.2 gradle-7.6.3 代理网络 2 下载springboot源码 代码仓库网址 git clone -b 2.7.x https://github.com/spring-projects/spring-boot.git3 安装gradle gradle下载网址 https://services.gradle.org/distributions/ 安装此文件指…

Three.js 3D人物漫游项目(上)

本文目录 前言1、项目构建1.1 安装依赖1.2 初始化1.3 项目结构1.4 初始化的项目运行 2、加载模型2.1 threejs三要素2.1.1 代码解读 2.2 加载模型2.2.1 代码解读 2.3 效果 前言 在数字技术的浪潮中&#xff0c;三维图形渲染技术以其独特的魅力&#xff0c;正逐步渗透到我们生活的…

基于无人机影像的可见光单木分割数据集-json格式

基于无人机影像的可见光单木分割数据集&#xff0c;共1700张影像&#xff0c;数据集大小3.6GB&#xff0c;分割标注采用标准json格式。 该数据集是一个专门用于基于无人机可见光影像进行单木分割的数据集&#xff0c;旨在帮助研究人员和开发者训练和评估基于深度学习的图像分割…

4.5 pandas 实战 分析抖音播放数据(1)

课程目标 基于pandas对抖音播放数据做数据分析 数据准备 点此去下载 课程内容 导包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns plt.rcParams["font.family"] "SimHei" plt.rcParams["ax…

道路坑洞分割数据集/道路裂纹分割数据集

1.道路坑洞,道路裂纹分割数据集&#xff0c;包含5790张坑洞分割图像数据&#xff08;默认分割标注png图片&#xff0c;850MB&#xff09;2.10000余张道路裂纹图像数据&#xff08;默认分割标注png图片&#xff0c;3.7GB&#xff09;3。道路坑洞&#xff0c;道路 道路坑洞与裂纹…

关于“华为杯”第二十一届中国研究生数学建模竞赛赛题下载及提交作品的重要提醒

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 各参赛队伍&#xff1a; “华为杯”第二十一届中国研究生数学建模竞赛即将于2024年…

零基础玩转实在Agent -- 基础篇|实在Agent研究

前言 实在Agent是什么 实在Agent&#xff08;智能体&#xff09;是实在智能基于RPA和自研屏幕语义理解技术&#xff0c;结合最前沿的Al大模型打造的自动化智能体产品。 它能像朋友一样聊天&#xff0c;并通过对话的方式理解你的任务需求&#xff0c;自动规划任务的实现方式&…

Qt clicked()、clicked(bool)、toggled(bool)信号的区别和联系

clicked() 信号 所属控件&#xff1a;clicked()信号是QAbstractButton类&#xff08;及其子类&#xff0c;如QPushButton、QRadioButton、QCheckBox等&#xff09;的一个信号。clicked信号可以说是许多控件&#xff08;特别是按钮类控件&#xff0c;如QPushButton&#xff09;…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0920)

十三、文章分类页面 - [element-plus 表格] Git仓库&#xff1a;https://gitee.com/msyycn/vue3-hei-ma.git 基本架子 - PageContainer 功能需求说明&#xff1a; 基本架子-PageContainer封装文章分类渲染 & loading处理文章分类添加编辑[element-plus弹层]文章分类删除…

Vue3DevTools7是如何在vscode定位指定文件位置的?

Vue3DevTools7是如何在vscode定位指定文件位置的&#xff1f; 背景 今天在使用vue脚手架创建项目的时候&#xff0c;并发现一个新的&#xff08;实验中的新功能&#xff09;&#xff0c;可以直接在我们的项目中集成Vue DevTools插件&#xff0c;浏览器插件devtools即将成为历史…

第十三周:机器学习笔记

第十三周周报 摘要Abstract一、机器学习——Transformer&#xff08;上&#xff09;1. Sequence to Sequence(Seq 2 Seq&#xff0c;序列到序列模型) 的应用2. Transformer的结构2.1 Transformer encoder&#xff08;Transformer 编码器&#xff09; 二、Pytorch学习1. 网络模型…

python爬虫初体验(一)

文章目录 1. 什么是爬虫&#xff1f;2. 为什么选择 Python&#xff1f;3. 爬虫小案例3.1 安装python3.2 安装依赖3.3 requests请求设置3.4 完整代码 4. 总结 1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Scraping&#xff09;是一种从网站自动提取数据的技术。简单来说&am…