N 辆车沿着一条车道驶向位于 target 英里之外的共同目的地。

每辆车 i 以恒定的速度 speed[i] (英里/小时),从初始位置 position[i] (英里) 沿车道驶向目的地。

一辆车永远不会超过前面的另一辆车,但它可以追上去,并与前车以相同的速度紧接着行驶。

此时,我们会忽略这两辆车之间的距离,也就是说,它们被假定处于相同的位置。

车队 是一些由行驶在相同位置、具有相同速度的车组成的非空集合。注意,一辆车也可以是一个车队。

即便一辆车在目的地才赶上了一个车队,它们仍然会被视作是同一个车队。

会有多少车队到达目的地?

示例:

输入:target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
输出:3
解释:
从 10 和 8 开始的车会组成一个车队,它们在 12 处相遇。
从 0 处开始的车无法追上其它车,所以它自己就是一个车队。
从 5 和 3 开始的车会组成一个车队,它们在 6 处相遇。
请注意,在到达目的地之前没有其它车会遇到这些车队,所以答案是 3。
提示:
0 <= N <= 10 ^ 4
0 < target <= 10 ^ 6
0 < speed[i] <= 10 ^ 6
0 <= position[i] < target
所有车的初始位置各不相同。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/car-fleet

这道题说是路上有一系列的车,车在不同的位置,且分别有着不同的速度,但行驶的方向都相同。如果后方的车在到达终点之前追上前面的车了,那么它就会如痴汉般尾随在其后,且速度降至和前面的车相同,可以看作是一个车队,当然,单独的一辆车也可以看作是一个车队,问我们共有多少个车队到达终点。这道题是小学时候的应用题的感觉,什么狗追人啊,人追狗啊之类的。这道题的正确解法的思路其实不太容易想,因为我们很容易把注意力都集中到每辆车,去计算其每个时刻所在的位置,以及跟前面的车相遇的位置,这其实把这道题想复杂了,其实并不需要知道车的相遇位置,只关心是否能组成车队一同经过终点线,那么如何才能知道是否能一起过线呢,最简单的方法就是看时间,假如车B在车A的后面,而车B到终点线的时间小于等于车A,那么就知道车A和B一定会组成车队一起过线。这样的话,就可以从离终点最近的一辆车开始,先算出其撞线的时间,然后再一次遍历身后的车,若后面的车撞线的时间小于等于前面的车的时间,则会组成车队。反之,若大于前面的车的时间,则说明无法追上前面的车,于是自己会形成一个新的车队,且是车头,则结果 res 自增1即可。

思路有了,就可以具体实现了,使用一个 TreeMap 来建立小车位置和其到达终点时间之间的映射,这里的时间使用 double 型,通过终点位置减去当前位置,并除以速度来获得。我们希望能从 position 大的小车开始处理,而 TreeMap 是把小的数字排在前面,这里使用了个小 trick,就是映射的时候使用的是 position 的负数,这样就能先处理原来 position 大的车,从而统计出正确的车队数量,参见代码如下:

解法一:

class Solution {
public:
int carFleet(int target, vector<int>& position, vector<int>& speed) {
int res = 0; double cur = 0;
map<int, double> pos2time;
for (int i = 0; i < position.size(); ++i) {
pos2time[-position[i]] = (double)(target - position[i]) / speed[i];
}
for (auto a : pos2time) {
if (a.second <= cur) continue;
cur = a.second;
++res;
}
return res;
}
};

我们也可以使用优先队列来做,由于其是按照从大到小的顺序自动排列的,所以不用使用上面的小 trick。还有一点和上面的不同的是,并没有在开始就计算过线时间,而是直接存的是速度,因为存整型肯定比存 double 型的要节省空间。在之后处理的时候,再取出位置和速度计算时间,然后再进行跟上面相同的操作即可,参见代码如下:

解法二:

class Solution {
public:
int carFleet(int target, vector<int>& position, vector<int>& speed) {
int res = 0; double cur = 0;
priority_queue<pair<int, int>> q;
for (int i = 0; i < position.size(); ++i) {
q.push({position[i], speed[i]});
}
while (!q.empty()) {
auto t = q.top(); q.pop();
double timeNeeded = (double)(target - t.first) / t.second;
if (timeNeeded <= cur) continue;
cur = timeNeeded;
++res;
}
return res;
}
};

方法一:排序

分析

我们首先对这些车辆按照它们的起始位置降序排序,并且用 (target - position) / speed 计算出每辆车在不受其余车的影响时,行驶到终点需要的时间。对于相邻的两辆车 S 和 F,F 的起始位置大于 S,如果 S 行驶到终点需要的时间小于等于 F,那么 S 一定会在终点前追上 F 并形成车队。这是因为在追上 F 之前,S 的行驶速度并不会减小,而 F 却有可能因为追上前面的车辆而速度减小,因此 S 总能在终点前追上 F。

算法

将车辆按照起始位置降序排序后,我们顺序扫描这些车辆。如果相邻的两辆车,前者比后者行驶到终点需要的时间短,那么后者永远追不上前者,即从后者开始的若干辆车辆会组成一个新的车队;如果前者不比后者行驶到终点需要的时间短,那么后者可以在终点前追上前者,并和前者形成车队。此时我们将后者到达终点的时间置为前者到达终点的时间。

Java

class Solution {
public int carFleet(int target, int[] position, int[] speed) {
int N = position.length;
Car[] cars = new Car[N];
for (int i = 0; i < N; ++i)
cars[i] = new Car(position[i], (double) (target - position[i]) / speed[i]);
Arrays.sort(cars, (a, b) -> Integer.compare(a.position, b.position)); int ans = 0, t = N;
while (--t > 0) {
if (cars[t].time < cars[t-1].time) ans++;
else cars[t-1] = cars[t];
} return ans + (t == 0 ? 1 : 0);
}
} class Car {
int position;
double time;
Car(int p, double t) {
position = p;
time = t;
}
}

Python

class Solution(object):
def carFleet(self, target, position, speed):
cars = sorted(zip(position, speed))
times = [float(target - p) / s for p, s in cars]
ans = 0
while len(times) > 1:
lead = times.pop()
if lead < times[-1]: ans += 1
else: times[-1] = lead return ans + bool(times)

复杂度分析

时间复杂度:O(NlogN),即为排序的时间复杂度。

空间复杂度:O(N),存储车辆到达终点需要的时间。

LeetCode——853.车队的更多相关文章

  1. [LeetCode] 853. Car Fleet 车队

    N cars are going to the same destination along a one lane road.  The destination is target miles awa ...

  2. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  3. LeetCode刷题总结-排序、并查集和图篇

    本文介绍LeetCode上有关排序.并查集和图的算法题,推荐刷题总数为15道.具体考点分析如下图: 一.排序 1.数组问题 题号:164. 最大间距,难度困难 题号:324. 摆动排序 II,难度中等 ...

  4. C#LeetCode刷题-栈

    栈篇 # 题名 刷题 通过率 难度 20 有效的括号 C#LeetCode刷题之#20-有效的括号(Valid Parentheses) 33.0% 简单 42 接雨水   35.6% 困难 71 简 ...

  5. [LeetCode] Car Fleet 车队

    N cars are going to the same destination along a one lane road.  The destination is target miles awa ...

  6. 【LeetCode】853. Car Fleet 解题报告(Python)

    [LeetCode]853. Car Fleet 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxu ...

  7. 边工作边刷题:70天一遍leetcode: day 85-3

    Zigzag Iterator 要点: 实际不是zigzag而是纵向访问 这题可以扩展到k个list,也可以扩展到只给iterator而不给list.结构上没什么区别,iterator的hasNext ...

  8. LeetCode.接雨水

    题外话:LeetCode上一个测试用例总是通不过(我在文章末贴出通不过的测试用例),给的原因是超出运行时间,我拿那个测试用例试了下2.037ms运行完.我自己强行给加了这句: && m ...

  9. [Swift]LeetCode853. 车队 | Car Fleet

    N cars are going to the same destination along a one lane road.  The destination is target miles awa ...

随机推荐

  1. 屏幕适配 - JS - 网站布局元素

    网页可见区域宽:document.body.clientWidth; 网页可见区域高:document.body.clientHeight; 网页可见区域高:document.body.offsetW ...

  2. Atomic系列类整体介绍

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 本文是转载文章,原文请见此博客,文章主要对java.ut ...

  3. matlab中自带的sobol的函数提供的sobol序列

    clc; clear all; close all; M=;% 维度,几个参数 nPop=; VarMin=[0.6, 0.10, 0.002, 0.02, 0.17, 0.0, 0.17, 0.0, ...

  4. Win7 node多版本管理gnvm采坑记录

    采坑描述:下载新node版本及切换node失败 解决:1.要用管理员权限启动cmd:2.确保node是空闲的 Gnvm下载地址: 32-bit | 64-bit Github 1.下载之后为 得到一个 ...

  5. Java9,8,7中接口的内容

    在Java 9+版本中,接口的内容可以有: 1:成员变量其实是常量格式:[public][static][final] 数据类型 常量名称 =数据值:注意: 常量必须进行赋值,而且一旦赋值不能改变 常 ...

  6. Essay写作没灵感怎么办?

    进入6月了,童鞋们都在干啥呢?有人回国玩耍了,有人周游欧洲了,当然也有人还在悲催地上课写作业.但是呢不管你此刻在哪里,final essay或者dissertation都离你不远啦!可是可是,有些留学 ...

  7. iOS内存管理布局及管理方案-理论篇

    苹果设备备受欢迎的背后离不开iOS优秀的内存管理机制,那iOS的内存布局及管理方案是怎样的呢?我们一起研究下. 内存管理分为五大块 栈区(stack):线性结构,内存连续,系统自己管理内存,程序运行记 ...

  8. Centos6.5 安装zabbix3(收藏,非原创)

    1.安装PHP Zabbix 3.0对PHP的要求最低为5.4,而CentOS6默认为5.3.3,完全不满足要求,故需要利用第三方源,将PHP升级到5.4以上,注意,不支持PHP7 rpm -ivh  ...

  9. Java语言概述-JavaSE

    代码虐我千百遍,我视代码如初恋 初级学习思想: 先了解Java 下载中英文文档对照学习 多看,多学 多敲,狂练 多标注注释 总结—创造 https://baike.baidu.com/(Java百度百 ...

  10. Java简单调用Lua

    package lua; import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFac ...