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
所有车的初始位置各不相同。
思路:
1.用car对象来存储每一辆车的起始位置和速度
2.根据距离的大小对car排序
3.从第一辆车开始判断,判断当前车与前车是否能组成车队,不能则将车队数sum加一,否则继续判断下一辆车。
4.注意的地方:后车追上后,与前车速度相同,再后面车也可能追上形成一个车队,所以用前车覆盖后车。
我的代码用距离来判断是否追上,官方用每辆车在不受其余车的影响时,行驶到终点需要的时间来判断是否追上,更简单。
代码:
class Solution {
public int carFleet(int target, int[] position, int[] speed) {
if (position.length == 0) {
return 0;
}
//1.用car对象来存储每一辆车的起始位置和速度
Car[] cars = new Car[position.length];
for (int i = 0; i < position.length; i++) {
cars[i] = new Car(position[i], speed[i], 0);
}
//2.根据距离的大小对car排序
Arrays.sort(cars);
//3.从第最后辆车开始判断,判断当前车与前车是否能组成车队,不能则将车队数sum加一,否则继续判断下一辆车。
int sum = 1; //初始化为1, 默认有一支车队
for (int i = position.length - 2; i >= 0; i--) {
//追不上
if (cars[i].speed <= cars[i + 1].speed || !isSame(cars[i], cars[i+1], target)) {
sum++;
}
}
return sum;
}
private boolean isSame(Car car1, Car car2, int target) {
//不能用int,因为时间不一定是整数
double dis1 = 0.1 * car1.speed*(car2.pos-car1.pos) * 10 / (car1.speed-car2.speed) + car1.pos;
double dis2 = 0.1 * car2.speed*(car2.pos-car1.pos) * 10 / (car1.speed-car2.speed) + car2.pos;
if (dis1 <= target && dis2 <= target){
//由于后车追上后就和前速度相同,为了后面的车便于判断,直接将前车覆盖后车
car1.pos = car2.pos;
car1.speed = car2.speed;
// 追上了
return true;
}
return false;
}
class Car implements Comparable<Car>{
int pos;
int speed;
public Car(int pos, int speed, int time) {
super();
this.pos = pos;
this.speed = speed;
}
@Override
public int compareTo(Car o) {
return this.pos - o.pos;
}
}
}