首页 > 编程语言 >算法学习每日一题之2332. 坐上公交的最晚时间:二分答案 & 贪心双指针

算法学习每日一题之2332. 坐上公交的最晚时间:二分答案 & 贪心双指针

时间:2024-09-18 14:55:58浏览次数:11  
标签:sort passengers 2332 capacity buses int vector 一题 贪心

Problem: 2332. 坐上公交的最晚时间

人话题意:你是一个懒惰的人,虽然你要赶公交车,但你想多睡会,恰好你知道每辆车的发车时间buses和每辆车容capacity,和每个乘客乘车的时间passenger,旨在求可以赶上公交车的最晚出发时间。

思路一:二分答案

求最晚能满足赶上公交的时间,可以发现答案具有二分性,比这个时间早一定赶得上公交,比这个时间晚就赶不上。
二分的关键在于寻找循环不变量,下界指向满足要求的,上界指向不满足要求的,这里我才用开区间写法(l, r),可以简化代码书写

根据提示, 2 < p a s s e n g e r [ i ] < 1 0 9 2< passenger[i] < 10^9 2<passenger[i]<109因此在1时刻之前出发都是满足要求的,所以初始l = 0,指向的时刻是满足要求的。乘客最晚时间 1 0 9 10^9 109,我们取开区间 + 1即可。接下来是check函数,我们只需要把我们的时刻添加到passenger中,再模拟 bus能承载的数量之内即满足要求

每次使用check函数都会创建一个数组,而且check函数两层循环,所以不管是时间还是空间复杂度都很高。

class Solution {
public:
    bool check(int time, vector<int>& buses, vector<int>& passengers, int capacity) {
        auto v = passengers;
        v.push_back(time);
        //基本有序可以使用插入排序
        ranges::sort(v);

        int j = 0;
        for(int t : buses)
        {
            for(int x = 0; j <= passengers.size() && v[j] <= t && x < capacity; ++x, ++j)
            {
                if(v[j] >= time) return true;
            }

        }
        return false;

    }
    int latestTimeCatchTheBus(vector<int>& buses, vector<int>& passengers, int capacity) {
        ranges::sort(buses);
        ranges::sort(passengers);
        int l = 0 , r = 1e9 + 1;
        while(l + 1 < r)
        {
            int mid = ((r - l + 1)>>1) + l;
            (check(mid, buses, passengers,capacity) ? l : r) = mid;
        }
        unordered_set<int> s;
        for (auto &x : passengers) s.insert(x);
        while (s.count(l)) {
            --l;
        }
        return l;
    }
};

思路二:贪心双指针

最晚出发,那我们就先考虑赶最晚那一趟车的最后一个到

  1. 如果最后那趟车没有满,那就无需插队,排到末尾,只要赶在公交车出发前到就行
  2. 如果满了那我们就赶在最后那个人之前到就行,此时再根据题目要求不能和其他乘客同时到,向前不断寻找没人到达的时刻进行插队即可。
class Solution {
public:
    int latestTimeCatchTheBus(vector<int>& buses, vector<int>& passengers, int capacity) {
        sort(buses.begin(), buses.end());
        sort(passengers.begin(), passengers.end());
        int j = 0, c;
        for(int x : buses)
        {
            for(c = capacity; c && j < passengers.size() &&passengers[j] <= x; c--)
            {
                j++;
            }
        }
        j--;
        //判断最后那趟车是否满,不满的话就赶在公交车出发之前到即可,满的话就进行插队,初始为最后那个人的时刻
        int ans = c ? buses.back() : passengers[j];
        while (j >= 0 && ans == passengers[j]) {
            ans--; // 往前找没人到达的时刻
            j--;
        }
        return ans;
    }
};

标签:sort,passengers,2332,capacity,buses,int,vector,一题,贪心
From: https://blog.csdn.net/2302_77423323/article/details/142333325

相关文章

  • 【每日一题】LeetCode 2332.坐上公交的最晚时间(数组、双指针、二分查找、排序)
    【每日一题】LeetCode2332.坐上公交的最晚时间(数组、双指针、二分查找、排序)题目描述给你一个下标从0开始长度为n的整数数组buses,其中buses[i]表示第i辆公交车的出发时间。同时给你一个下标从0开始长度为m的整数数组passengers,其中passengers[j]表示第......
  • sicp每日一题[2.13-2.16]
    Exercise2.13Showthatundertheassumptionofsmallpercentagetolerancesthereisasimpleformulafortheapproximatepercentagetoleranceoftheproductoftwointervalsintermsofthetolerancesofthefactors.Youmaysimplifytheproblembyassu......
  • 贪心算法-找不重叠的区间段
    1.说明有N个区间片段,查找其中不重叠的片段最大个数。例如(68),(24),(35),(15),(59),(810)这6个片段中,不重叠的片段最大个数为3,分别为(24),(68),(810)。2.解析先按照起始位置从小到大进行排序,使用贪心算法使有效片段尽可能小,即结束位置更靠前。当前片段如果属于上个有效片段的子段,......
  • sicp每日一题[2.10]
    Exercise2.10BenBitdiddle,anexpertsystemsprogrammer,looksoverAlyssa’sshoulderandcommentsthatitisnotclearwhatitmeanstodividebyanintervalthatspanszero.ModifyAlyssa'scodetocheckforthisconditionandtosignalanerror......
  • Java LeetCode每日一题
            1184.公交站间的距离    需求:        环形公交路线上有n个站,按次序从0到n-1进行编号。我们已知每一对相邻公交站之间的距离,distance[i]表示编号为i的车站和编号为(i+1)%n的车站之间的距离。        环线上的公交......
  • Supermarket(贪心)
    #include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedeflonglongll;typedefpair<int,int>PII;voidsolve(){intn;while(cin>>n){vector<PII>a(n);for(inti=0;i<n;+......
  • 贪心算法(算法详解+模板+例题)
    1.贪心是什么贪心算法(GreedyAlgorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好的策略。虽然这种策略并不保证一定能得到全局最优解,但在许多情况下,它能提供近似最优解,而且计算效率高。贪心算法通常适用于那些具有“最优......
  • 算法入门-贪心1
    第八部分:贪心409.最长回文串(简单)给定一个包含大写字母和小写字母的字符串s,返回通过这些字母构造成的最长的回文串的长度。在构造过程中,请注意区分大小写。比如"Aa"不能当做一个回文字符串。示例1:输入:s="abccccdd"输出:7解释:我们可以构造的最长的回文串是"......
  • Java知识及每日一题Day3
    Day32024年9月8日14:23:37再次跟上Java的补漏学习,重点关注细节知识点,强化重点。一、入门程序编码没有问题,顺便复习一下dos命令:创建文件夹并切换路径mkdirD:\JavaLearning\JavaLesson\DemocdD:\JavaLearning\JavaLesson\Demo创建文件并使用记事本打开(需要管理......
  • Day4_Java知识及每日一题:最长回文串
    Day42024年9月9日15:38:20一、java文件名和类名一致性问题首先明确,不是必须一致。若一个类是公共(public)的,则应该在一个同名的java文件中声明。反之default类型的类声明则可以成功通过编译,编译后的.class文件和所声明的类名一致。publicclassDemo01_HelloWorld{pu......